Promise는 객체로써 언젠가 완료될 일(계산)을 나타냅니다. 완료되면 하나의 값을 결과로 반환하는데 실패하여 정상적인 값 대신 실패의 이유를 반환할 수도 있습니다.

Promise 객체는 다음과 같은 세 가지의 상태를 가집니다.

  • 대기중(Pending): 아직 결과가 없는 상태입니다. 약속을 했지만 아직 약속에 대한 결과가 나오지 않은 상태를 말합니다.
  • 이행됨(Fulfilled): 비동기 처리가 성공적으로 완료되어 약속을 이행한 상태입니다. 이때 결과로 하나의 값이 전달됩니다.
  • 거부됨(Rejected): 비동기 처리가 실패한 상태입니다. 약속이 거부되고 그 결과로 거절된 이유를 전달합니다.

Promise 객체는 다음 두 가지 메소드를 가집니다.

  • then(onFulfilled, onReject): 약속이 완료됐을 때 호출될 함수들을 정의합니다. 이때 첫 번째 인자로 전달되는 함수는 약속이 성공적으로 이행됐을 때 호출되고 두 번째 인자로 전달된 함수는 거부됐을 때 호출됩니다. 두 전달 인자 함수들은 매개변수를 가지는데 각 각의 결과가 매개변수를 통해 전달됩니다.
  • catch(onReject): 약속이 거부됐을 때 호출될 함수(onReject)를 등록합니다.

다음의 그림에서 객체는 비동기 코드를 가지며 대기 중인 상태로 만들어지고 이후 비동기 코드 에서 resolve reject를 호출하면 Promise 객체에 등록한 어떠한 함수들이 호출되는지를 보여 줍니다.

1  function promiseForHomework (mustDo) {
2    return new Promise((resolve, reject) => {
3      setTimeout(() = {
4        console.log('doing homework');
5        if(mustDo) {
6          resolve({
7            result: 'homework-result'
8          });
9        } else {
10        reject(new Error('Too lazy!'));
11       }
12     }, 3000);
13   });
14 };
15
16 const promiseA = promiseForHomework (true);
17 console.log('promiseA created');
18
19 const promiseB = promiseForHomework();
20 console.log('promiseB created');
21
22 promiseA.then(v => console.log(v));
23 promiseB
24   .then(v>console.log(v))
25   .catch(e>console.error(e));

1라인

숙제에 대한 Promise 객체를 생성하는 함수를 정의합니다. 이때 매개변수로 mustDo를 정의하고 mustTo에 의해 Promise에 대한 성공과 실패를 결정합니다.

2라인

Promise 객체는 Promise 생성자 함수에 new 키워드를 통해 생성할 수 있습니다. 이때 계산될 코드를 담은 함수를 인자로 전달하는데 이 함수에는 resolve와 reject 매개변수를 가집니다. resolve는 약속을 성공시킬 수 있는 함수로 호출 시 결과를 인자로 전달합니다. 반면 reject는 실패 처리를 위한 함수로 호출 시 실패 이유를 함께 전달할 수 있습니다. 즉, Promise 생성자 함수에 전달되는 함수의 본문에는 나중에 계산이 완료되는 일을 작성하게 됩니다.

3~12라인

setTimeout 함수를 통해 3초 후에 실행될 코드를 정의합니다. 콘솔에 'doing homework'을 출력하는 코드는 3초 후에 실행되고, promiseForHomework 전달받은 인자 값의 유무에 따라 resolve 함수 또는 reject 함수가 호출됩니다. resolve 함수가 호출되면 이후에 then 메소드에 전달된 첫 번째 인자의 함수가 호출되고, 이때 resolve에 전달한 전달 인자가 then 메소드의 전달된 함수의 매개변수로 전달됩니다.

16~17라인

새로운 숙제 Promise 객체를 생성합니다. 이때 true를 인자로 전달하여 3초 후에 약속이 꼭 이행되게 합니다. 그리고 콘솔에 'promiseA created'를 출력합니다. 4라인의 코드보다 나중에 작 성하였어도 4라인은 3초 후에 실행되는 비동기 코드이기 때문에 콘솔에 'promiseA created'가 먼저 출력됩니다.

19~20라인

또다른 숙제 Promise 객체를 생성합니다. 마찬가지로 콘솔에 'promiseA created'가 ’doing homework' 보다 먼저 출력되고 이전의 숙제 Promise와 다르게 전달 인자가 없이 생성하여 3초 후에 reject가 호출됩니다.

22-25라인

각 Promise 객체에 resolve와 reject가 되었을 경우 호출될 함수들을 정의합니다. promiseA 객체는 resolve가 되어 “{result:"homework-result"}"가 콘솔에 출력되고, promiseB 객체는 reject가 되서 24라인에 전달한 함수는 호출이 안 되고 catch 메소드에 전달한 함수가 호출되어 거절된 이유인 에러 객체가 콘솔에 에러로 출력됩니다.

위 코드를 크롬 콘솔에서 확인하면 다음과 같습니다.

// 결과
promiseA created
promiseB created
doing homework
{result: "homework-result"}
doing homework
Error: Too lazy!

0 댓글