Javascript에서 비동기 처리를 다루는 방법에는 여러가지가 있다. 주로 Callback, Promise, Async/Await, Generator/Yield를 활용한다.
Callback함수를 여러 개 중첩하면 작업내용을 이해하기 어려워지는데 콜백 지옥(Callback Hell)이라 한다. Promise를 이용하면 비동기 처리도 간결하게 작성할 수 있다.
Promise를 사용하려면 먼저 Promise객체를 생성해야 한다.
Promise는 자바스크립트에서 비동기 처리에 사용되는 객체(비동기 작업의 단위)이다.
이전 작업이 완료될 때 까지 다음 작업을 연기 시키거나, 작업실패를 대응할 수 있는 비교적 새로운 JavaScript 기능.
Promise의 3가지 진행 상태
const promise = new Promise((resolve, reject)=>{
// code...
// 성공 시
resolve("성공.");
// 실패 시
reject(new Error('실패.'));
});
promise
.then(value => console.log(value)) // resolve를 받음
.catch(err => console.log(err)); //reject를 받음
then 메소드는 해당 Promise가 성공했을 때의 동작을 지정(인자로 함수)
catch 메소드는 해당 Promise가 실패했을 때의 동작을 지정(인자로 함수)
위 함수들은 체인 형태로 활용 가능.
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
}).then(function(result) {
alert(result); // 1
return result * 2;
}).then(function(result) {
alert(result); // 2
return result * 2;
}).then(function(result) {
alert(result); // 4
return result * 2;
});
Promise Chaining이 가능한 이유는 promise.then을 호출하면 Promise가 반환되기 때문. 반환된 Promise엔 당연히 .then을 호출할 수 있다.
한편 핸들러가 값을 반환할 때엔 이 값이 promise result가 되서 다음 .then은 이 값을 이용해 호출.
하지만 이것도 콜백지옥의 약간의 개선판으로 then()지옥이라 불린다.
여러가지 작업을 동시에 병렬로 처리하고 싶다면 Promise.all을 사용할 수 있다.
내가 처리하고자 하는 프로미스들을 배열로 담아 Promise.all에 인자로 전달하면
배열에 있는 모든 프로미스들이 거의 동시에 트리거된다.
promise.all()을 사용할 때 주의해야할 점은 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부한다.
const promise1 = new Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo1');
});
const promise4 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo2');
});
Promise.all(
[promise1, promise2, promise3, promise4])
.then((values) => {
console.log(values);
}); -> [3, 42, "foo1","foo2"]
Promise.race()는 Promise.all()과 마찬가지로 배열과 같은 iterable한 객체를 매개변수로 받는다.
그리고 배열에 담긴 Promise를 병렬로 실행하는데, Promise.all()이 실행한 모든 프로미스들의 결과값을 배열로 받는 것과 달리 Promise.race()는 가장 빨리 응답을 받은 결과값만 resolve한다.
var p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('하나'), 1000);
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('둘'), 2000);
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve('셋'), 3000);
});
var p4 = new Promise((resolve, reject) => {
setTimeout(() => resolve('넷'), 4000);
});
Promise.race([p1, p2, p3, p4, p5])
.then(value => {
console.log(value);
}); -> '하나'
Promise의 resolve, reject와 관계없이 Promise가 처리 된 후에 코드가 무조건 한 번은 실행된다.
const promise = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo1');
});
promise
.then(value => console.log(value)) // resolve를 받음
.catch(err => console.log(err)); //reject를 받음
.finally(() => console.log('finally')); // 무조건 실행
자바스크립트에서는 비동기 처리를 다룰 수 있는 방법에는 여러가지가 있다. 주로 Callback, Promise, Async/Await 를 활용한다.
Async/Await은 가장 최근의 나온 비동기 처리 문법으로 기존의 callback 이나 Promise 의 단점을 해소하고자 만들어졌다.(콜백지옥, then지옥)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise