정해진 기능을 수행하고 완료되면 정보를 전달, 중간에 문제가 생기면 오류를 전달하는 JS 객체
Promise의 내부 프로퍼티
1. state(상태) : pending
-> fulfilled
or rejected
2. result(결과) : undefined
-> value
or error
📌 프라미스 객체의 state, result 프로퍼티는 내부 프로퍼티이므로 개발자가 직접 접근할 수 없음
=> .then
/.catch
/.finally
메서드를 사용하면 접근 가능
Producing Code
const promise = new Promise((resolve, reject) => {
//doing some heavy work (network, read files)
console.log("doing something...");
setTimeout(() => {
resolve("완료");
}, 2000);
});
// doing something... (즉시 출력)
// 완료 (2초 후 출력)
Promise를 생성한 순간 바로 executor 함수가 실행됨
(만약 네트워크 통신 관련된 코드가 있었으면 바로 실행했을 것)
*executor 함수는 Promise 객체에서 매개변수로 받는 함수
=> 사용자가 원하지 않은 불필요한 네트워크 통신이 일어날 수도 있음
📌 네트워크와 통신을 한다던지, 파일을 읽어오는 등의 작업은 비동기적으로 처리하는 것이 바람직
*동기적으로 처리하면 시간이 오래 걸리는 작업을 하는 동안 다음 코드를 못읽어내려감
const promise = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error("에러 발생!")), 2000);
});
// 2초 뒤에 에러와 함께 실행이 종료되었다고 뜸.
📌 무언가 잘못된 경우, executor는 reject를 호출해야 하며 이때 reject의 인수는 resolve와 마찬가지로 어떤 타입도 가능하지만 JS의 Error 객체 또는 Error를 상속받은 객체를 사용하는 것이 바람직.
Consuming Code: then, catch, finally
promise.then
: promise가 성공적으로 실행되었을 때 성공한 값을 전달.
promise.then(
function(result){/* result를 이용한 함수 */},
function(error){/* error를 이용한 함수 */}
);
promise.catch
: 실행 중 문제가 생겼을 때 error를 전달
promise.finally
: promise 실행 성공 여부와 상관 없이 항상 실행됨
📌 프라미스 체이닝이 가능한 이유는 promise.then을 호출하면 state와 result를 가진 프라미스가 반환되기 때문
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2초가 지났습니다.');
resolve('hello');
}, 2000);
});
// consol.log 실행
// result로 'hello'를 가짐
promise.then(msg => {
console.log(msg); // hello
});
// 2초가 지난 후 '2초가 지났습니다.' 출력 후 result인 hello 출력
// then 메소드에서 인자로 전달받는 것은 promise의 result
Promise chaining
const fetchNb = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000)
}); // 1초를 기다렸다가 1을 전달
fetchNb
.then(num => num * 2) // 2
.then(num => num * 3) // 6
.then(num => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num - 1), 1000);
})
}) // then에서 값 뿐만 아니라 새로운 Promise를 전달할 수도 있음
.then(num => console.log(num)); // 5 출력
장점
.then
에 작성하면 가독성이 좋음.then
을 호출할 수 있음function delay(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve, ms);
})
} // resolve는 반환 값이 필요 없을 때 인수 없이 호출될 수 있음
delay(3000).then(() => alert('3초후 실행'));