[JS] Promise 조합하기
하나의 비동기 계산이 다른 비동기 계산의 결과에 의해 처리되어야 하는 경우가 많습니다. Promise가 나오기 이전에는 콜백 패턴을 통해 비동기 처리를 하였고, 중첩된 비동기 코드들을 처리하다 보면 콜백 피라미드 형태의 코드들이 쉽게 나왔었습니다.
이런 비동기 코드들의 조합을 Promise 기반으로 작성하면 명료한 코드를 작성할 수 있고 예외 처리를 손쉽게 할 수 있습니다. Promise의 then 메소드에서 새로운 비동기 코드를 실행하는 Promise를 반환할 수 있는데 다음 then 메소드는 새롭게 만들어진 Promise 코드가 이행되기 전까지 호출되지 않습니다.
다음의 예제는 1초 후에 주어진 이름의 일을 수행하여 이행 시 스테미나를 차감할 값을 반환합니다. 1초 후에 일을 수행하는 약속(Promise)를 연속적으로 처리하게 됩니다.
1 function doJob(name, person) {
2 return new Promise((resolve, reject) => {
3 setTimeout(() = {
4 if(person.stamina > 50) {
5 resolve({
6 result: `${name} success`,
7 loss: 30
8 });
9 } else {
10 reject(new Error(`${name} failed`));
11 }
12 }, 1000);
13 });
14 };
15
16 const harin = {stamina: 180};
17
18 doJob('work', harin)
19 .then(v => {
20 console.log(v.result);
21 harin.stamina -= v.loss;
22 return doJob('study', harin);
23 })
24 .then(v => {
25 console.log(v.result);
26 harin.stamina -= v.loss;
27 return doJob ('work', harin);
28 })
29 .then(v => {
30 console.log(v.result);
31 harin.stamina -= v.loss;
32 return doJob('study', harin);
33 })
34 .catch(e => console.error(e));
1~4라인
주어진 이름에 일을 수행하는 약속을 생성하는 doJob 함수를 정의합니다. 스테미나(stamina)를 속성으로 갖는 객체를 매개변수로 전달받아 스테미나가 50보다 많으면 약속이 이행됩니다. 이행 결과로는 스테미나를 차감할 값을 포함하는 객체를 전달합니다. 그리고 스테미나가 50 이 하면 약속은 거부됩니다.
16라인
스테미나 값 100을 가지는 객체를 정의합니다.
18~23라인
work 이름의 일을 수행하는 약속을 생성합니다. 전달된 인자의 스테미나가 100이기 때문에 성공적으로 이행되고 then 메소드 전달한 콜백 함수에 차감될 스테미나와 결과값이 전달됩니다. 그리고 then 메소드에 전달한 콜백 함수에서 study 이름의 일을 수행하는 약속을 반환합니다. 이렇게 반환된 약속이 이행되면 다음에 연결된 then 메소드의 콜백 함수에서 앞서 반환한 약속의 이행 결과가 전달됩니다.
24~27라인
공부하는 약속에 이행된 결과를 콘솔에 출력하고 스테미나를 차감합니다. 그리고 다시 work 이름의 일을 수행하는 약속을 생성하여 반환합니다.
29~33라인
이전 then 메소드 콜백 함수에서 반환된 work 이름의 일을 수행하는 약속의 이행 결과를 인자로 전달 받습니다. 하지만 이전까지의 수행된 일들 때문에 스테미나가 50 이하까지 차감되어 이 콜백 함수는 호출되지 않습니다. 왜냐하면 이전 약속이 거부되었기 때문입니다.
34라인
앞에 이어지는 약속들의 연결에서 에러가 발생하게 되면 catch 메소드의 콜백 함수가 호출됩니다. 24라인의 then 메소드의 전달된 콜백 함수에서 반환한 약속이 거부되면서 해당 catch 메소드의 콜백 함수가 호출됩니다.
위 코드를 크롬 콘솔에서 확인하면 다음과 같습니다.
// 결과
work success
study success
Error: work failed
0 댓글