promise
promise
이 포스트는 JavaScript
비동기 프로그래밍에 관한 포스트입니다.
비동기처리와 관련된 설명은 링크를 참고하여 주세요.
promise란,
promise
는 생성 시 꼭 알려지지 않아도 되는 proxy
로써, 결과 값이나 실패 이유를 처리할 수 있게 핸들러와 연결시켜 준다.
프로미스는 비동기적 메서드를 동기적 메서드처럼 값을 리턴하게 해준다. 바로 최종 상황을 리턴하지는 않고, 프로미스를 반환하여 어떤 시점에 결과를 제공할 수 있다.
프로미스는 아래와 같은 상태 중 하나를 가지게 된다.
pending
(대기): 이행하거나 거부되지 않은 초기상태이다.fulfield
(이행): 오퍼레이션이 성공적으로 완료됨.rejected
(거부): 오퍼레이션이 실패함.
대기 프로미스는 거부 혹은 이행상태로 진입가능하며, 이 상태로 진입하게 되면, 핸들러는 프로미스의 then
메서드에 의해 대기열에 오르게 된다.
Promise.prototype.then()
와 Promise.prototype.catch()
메서드는 다른 프로미스를 반환하므로 서로 연결할 수 있다.
프로미스는 오브젝트 안에 오브젝트를 포함하는 특별한 형태의 자바스크립트 오브젝트로써 비동기를 강제하는 역할을 할 수 있다.
위에서 언급했 듯이 시점은 상관없으며, 어떤 경우에도 then()
을 부르기만 하면 된다.
promise 사용법
const condition = true; // true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => {
if (condition) {
resolve('성공');
} else {
reject('실패');
}
});
// 다른 코드가 들어갈 수 있음
promise
.then((message) => {
console.log(message); // 성공(resolve)한 경우 실행
})
.catch((error) => {
console.error(error); // 실패(reject)한 경우 실행
})
.finally(() => { // 끝나고 무조건 실행
console.log('무조건');
});
new Promise
를 통해 프로미스 생성이 가능하며, 안에 resolve
, reject
를 파라미터로 갖는 콜백 함수를 넣어준다.
resolve
-> then
, reject
-> catch
가 실행된다.
resolve
, reject
에서 파라미터는 message
로 받을 것이다.
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
.then((result) => {
console.log(result); // ['성공1', '성공2'];
})
.catch((error) => {
console.error(error);
});
위 코드는 프로미스 객체 여러 개를 한 번에 처리하는 방법이다.
Promise.resolve
는 즉시 resolve를 하는 프로미스를 만드는 방법이다. 여러 개 있을 경우 Promise.all
에 넣으면 모두 resolve될 때까지 기다렸다가 then
으로 넘어간다. 하나라도 reject
된다면 catch
로 넘어간다.
Refernce doc 고급예제
'use strict';
var promiseCount = 0;
function testPromise() {
var thisPromiseCount = ++promiseCount;
var log = document.getElementById('log');
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') 시작 (<small>동기적 코드 시작</small>)<br/>');
// 새 프로미스 생성 - 프로미스의 생성 순서를 전달하겠다는 약속을 함 (3초 기다린 후)
var p1 = new Promise(
// 실행 함수는 프로미스를 이행(resolve)하거나
// 거부(reject)할 수 있음
function(resolve, reject) {
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') 프로미스 시작 (<small>비동기적 코드 시작</small>)<br/>');
// setTimeout은 비동기적 코드를 만드는 예제에 불과
window.setTimeout(
function() {
// 프로미스 이행 !
resolve(thisPromiseCount);
}, Math.random() * 2000 + 1000);
}
);
// 프로미스를 이행했을 때 할 일은 then() 호출로 정의하고,
// 거부됐을 때 할 일은 catch() 호출로 정의
p1.then(
// 이행 값 기록
function(val) {
log.insertAdjacentHTML('beforeend', val +
') 프로미스 이행 (<small>비동기적 코드 종료</small>)<br/>');
})
.catch(
// 거부 이유 기록
function(reason) {
console.log('여기서 거부된 프로미스(' + reason + ')를 처리하세요.');
});
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') 프로미스 생성 (<small>동기적 코드 종료</small>)<br/>');
}
다음의 작은 예제는 Promise의 동작 방식을 보여줍니다. testPromise() 함수는 button을 클릭할 때마다 호출되며, window.setTimeout()을 사용해 1~3초의 무작위 간격 이후 프로미스 횟수(1부터 시작하는 숫자)로 이행하는 프로미스를 생성합니다. Promise() 생성자는 프로미스를 만드는 데 쓰입니다.
프로미스 이행은 p1.then()을 사용하는 이행 콜백 세트를 통해 단순히 로그에 남습니다. 약간의 로그를 통해, 함수의 동기 부분이 비동기적 프로미스의 완료와 어떻게 분리되어 있는지 확인할 수 있습니다.
Refernce
- 조헌영, Node.js 교과서, 길벗, 2장 알아두어야 할 자바스크립트
- https://medium.com/@kiwanjung/%EB%B2%88%EC%97%AD-async-await-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-%EC%A0%84%EC%97%90-promise%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-955dbac2c4a4
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise