저번 글에서 callback함수에 따른 js의 비동기 처리, 그리고 callback함수의 불편함에 의한 promise의 사용법을 알아보았다.
이번 글에선, 이렇게 만들어진 promise객체를 반환하는 함수를 더욱 직관적으로 만들어 주는 await/async에 대해 알아보자.
function test() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("success!");
}, 2000)
})
}
test().then(function(result) {
console.log("success!");
}).catch(function(error) {
console.log(error);
})
이렇게 저번글에서서 Promise객체를 통해 비동기 처리를 하는 법을 알아보았다.
promise객체의 반환값은 resolve 또는 reject 에 담기고, resolve시에는 then의 callback함수를 통해, reject시에는 catch의 callback함수를 통해 그 결과물을 확인 할 수 있었다.
개발을 하다보면, 코드의 가독성은 매우 중요하다.
교수님께선 종종 현업에 가면 너가 새롭게 코드를 다 짜는 일은 거의 없고, 코드를 수정해나가는게 대부분이라 하셨고 다른 사람이 작성한 코드를 읽는 것은 매우 중요하다 하셨다. await/async는 코드의 가독성을 매우 좋게 해준다. 비동기 처리가 매우 읽기 쉬워지는 것이다.
async function test() {
return 1;
}
async는 function앞에 위치한다.
function 앞에 async를 붙이면 해당 함수는 항상 Promise를 반환한다. Promise가 아닌 값을 반환하더라도 이행 상태의 프라미스(resolved promise)로 값을 감싸 이행된 프라미스가 반환되도록 합니다.
async function test() {
return Promise.resolve(1);
}
명시적으로 프라미스를 반환하는 것도 가능하다.
async function test() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
await promise;
}
await는 async 함수 안에서만 동작한다. 또한 await는 promise를 반환하는 함수에 앞에만 사용할 수 있다. await는 말 그대로 Promise가 처리될 때까지 함수 실행을 기다리게 만든다.
node.js가 싱글 스레드라 대기 중에 아무것도 못할 것 같지만, Promise가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
async function errorTest() {
const errorResponse = await Promise.reject(1);
}
await/async에서 Promise객체가 reject를 반환하여 에러가 발생할때는 어떻게할까?
new Promise(function(resolve, reject) {
reject("error!");
}).then(function(result) {
console.log("success!");
}).catch(function(error) {
console.log(error);
})
await/async를 사용하지 않았을때는 then..catch를 사용해야 했지만,
async function errorTest() {
try{
const errorResponse = await Promise.reject(1);
} catch(error) {
console.log(error);
}
}
await가 던진 에러는 throw가 던진 에러를 잡을 때처럼 try..catch를 사용해 잡을 수 있다.