function double(num) {
return setTimeout(() => {
const doubleNum = num * 2;
return doubleNum;
}, 1000);
}
const res = double(10);
console.log(res); // ???
double 함수를 호출하면 setTimeout 함수에 의해 1초 뒤에 20이 출력될 것 같지만, 출력되는 값은 알 수 없는 값이다. 게다가 다시 한 번 실행하면 이전과 다른 값이 출력되는 것을 확인할 수 있다. 이 때 콘솔에 출력된 알 수 없는 숫자는 인수로 전달한 콜백 함수의 반환값이 아니라 타이머의 식별 번호일 뿐이다.
그렇다면 사용자가 이 함수를 작성한 의도에 맞게, 인수로 전달한 값에 2를 곱한 값을 반환해서 출력하게 하려면 어떻게 해야 할까?
function double(num, cb) {
setTimeout(() => {
const doubleNum = num * 2;
cb(doubleNum);
}, 1000);
}
double(10, (res) => {
console.log(res);
});
console.log("마지막");
// 마지막
// 20
바로 콜백 함수의 인수로 2를 곱한 결괏값을 전달해서, 비동기 작업의 결괏값을 반환값으로 사용하는 것이다.
이렇게 콜백함수를 이용하면 비동기 작업의 결과값을 사용할 수 있다.
프로미스(Promise)
- 비동기 처리를 목적으로 제공되는 자바스크립트 내장 객체.
- 특수한 목적을 위해 다양한 기능이 추가된 객체.
프로미스를 이용하면 콜백 함수를 이용한 비동기 처리보다 더 쉽게 비동기작업을 수행할 수 있다.
프로미스는 세 가지 상태를 가질 수 있다.
기본적으로 대기(pending)
상태이며, 대기 상태에서 작업을 성공적으로 해결(resolve)
하면 성공(fulfilled)
상태가 되고, 작업이 모종의 이유로 실패(reject)
한다면 실패(rejected)
상태가 된다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log("안녕");
}, 500);
});
// 안녕
프로미스 객체를 생성할 때는 인수로 실행 함수를 전달하는데, 주로 콜백함수이며 2개의 매개변수를 받는다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("성공");
}, 500);
});
promise.then(function (res) {
console.log(res);
});
// 성공
프로미스 객체는 0.5초 뒤에 resolve를 호출하고 인수로 "성공"이라는 문자열을 전달한다. 이 인수는 promise.then 메서드에 인수로 전달한 res가 받는다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("실패");
}, 500);
});
promise.catch(function (err) { ①
console.log(err);
});
// 실패
프로미스 객체는 0.5초 뒤에 reject를 호출하고 인수로 "실패"라는 문자열을 전달한다. 이 인수는 promise.catch 메서드에 인수로 전달한 res가 받는다.
작업 실패 시 reject를 호출한 프로미스 객체에 대해서는 then 메서드가 실행되지 않는다.
이처럼 프로미스의 then 메서드와 catch 메서드를 통해 좀 더 유연한 비동기 처리가 가능하다❗️