ES6
에서 Promise
를 도입하였습니다.Promise
객체는 비동기 계산을 위해 사용됩니다. promise
는 아직은 아니지만 나중에 완료될 것으로 기대되는 연산을 표현합니다.
Promise는 단어 그대로 나중에 연산하기 위한 "약속" 같은 개념입니다.
Promise는 비동기 요청에 대하여, 비동기 실행이 완료된 후 결과 값 또는 실패의 이유로 콜백 함수로 전달합니다.
따라서 비동기 실행이 정상적으로 되었는지, 오류가 발생하였는지 알 수 있도록 상태가 정의되어 있어야 합니다.
다음은 promise를 사용하는 간단한 예제입니다.
let lab = function(bool){
return new Promise(function(resolve, reject){
setTimeout( function(){
if(bool){
resolve("fulfilled 상태입니다. then으로 연결됩니다.");
}
else{
reject("rejected 상태입니다. catch로 연결됩니다.");
}
}, 1000)
})
}
lab(true)
.then( function(result){
console.log(result);
})
.catch( function(err){
console.log(err)
})
then()
메서드는 호출한 Promise가 resolve()를 호출하였을때 반환값을 콜백함수로 받아주며, 이때 새로운 Promise를 반환합니다.
catch()
메서드는 호출한 Promise가 reject()를 호출했을 때 반환 값을 콜백함수로 받아주며, 이 때도 새로운 Promise를 반환합니다.
위의 예제 처럼 lab() 함수를 호출할 때 true
를 인자로 전달하였기 때문에 비동기 함수인 setTimeout()에서 resolve(0메서드가 실행되기 때문에 fulfilled
상태입니다.
lab(false);
로 함수를 호출하면 catch()가 실행됩니다.즉, then()과 catch()는 동시에 수행되지 않습니다.
all()
메서드를 호출할 때, 인자로 여러 Promise 들을 넘겨줍니다.var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 2000, "promise1");
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000, "promise2");
});
Promise.all([promise1, promise2]).then(function(value) {
console.log(value);
});
race()
메서드를 호출할 때, 인자로 여러 Promise들을 넘겨줍니다.var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 2000, "promise1");
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000, "promise2");
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
});
promise2
가 출력됩니다.하지만 Promise를 사용해도 여전히 코드가 복잡합니다.그래서 ES8 에서 async와 await를 도입하였고, 덕분에 비동기 코드를 동기적으로 깔끔하게 처리할 수 있게 되었습니다.
그렇다고 해서 항상 async/await가 옳다고 할 수 없습니다.
async funtion foo(){
await someAsyncFunction(){..}
await anotherAsyncFunction(){...}
}
핵심은 await
이며 , async
는 단지 선언용입니다.
즉 , 함수 앞에 async가 선언되어 있어야만 await 키워드를 사용합니다.
someAsyncFunction
, anotherAsyncFunction
두 함수가 비동기 코드일 지라도 async/await 가 적용되면, 항상 someAsncFunction
-> anotherAsyncFuntion
순서대로 함수가 실행 됩니다.async functino test(){
await foo(1,2000);
await foo(2,500);
await foo(3,1000);
}
function foo(num,sec){
setTimeout(function(){
console.log(num);
},sec);
}
test();
// 2, 3, 1
async function test(){
await foo(1,2000);
await foo(2,500);
await foo(3,1000);
}
function foo (num,sec){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(num);
resolve('async는 Promise 방식을 사용합니다');
},sec);
});
}
// 1,2,3
function test(){
foo(1,2000)
.then( () => {
return foo(2,500)
})
.then( () => {
return foo(3,1000)
})
}
function foo(num, sec){
return new Promise(function(resolve, reject){
setTimeout( function(){
console.log(num);
resolve("async는 Promise방식을 사용합니다.");
}, sec);
});
}
test();
async function test(){
await foo(1, 2000)
await foo(2, 500).then( () => {
foo(3, 1000)
})
}
function foo(num, sec){
return new Promise(function(resolve, reject){
setTimeout( function(){
console.log(num);
resolve("async는 Promise방식을 사용합니다.");
}, sec);
});
}
test();