async/await 패턴은 es8에서 도입되었는데 es6에서 표준화된 Promise 패턴으로도 불편함이 있었고 이 불편함을 해소하기 위해서 async/await 패턴이 도입되었다. 따라서 반드시 Promise 패턴을 알고 있어야 한다.
async/await에서 사용되는 몇가지 규칙이 있다.
- await 는 반드시 async와 같이 사용되어야 한다.
- await 뒤에는 반드시 Promise 객체가 와야 한다.
- await는 Promise 객체의 비동기 작업이 끝날때까지 동기방식처럼 blocking 되어서 기다렸다가 작업이 끝나면 그 결과를 리턴한다.
- async를 앞에 붙인 함수는 resolved 된 Promise를 리턴하므로 만일 결과를 받아서 사용할려면 .then()으로 결과를 받아서 처리할 수 있다.
async
function 앞에 async를 붙이면 해당 함수는 Promise 객체를 반환하고 비동기 함수가 된다.
Promise가 아닌 값을 return 해도 resolve된 Promise로 래핑해서 반환한다.
아래처럼 resolve를 쓰지 않고 async 키워드를 붙이고 return을 하니 promise 객체가 반환된다.
a = async () => {
return('duck');
}
console.log(a());
// Promise { 'duck' }
위와 결과가 같다
async function a() {
return 'duck';
}
b = a();
console.log(b);
//duck
await
await는 async 함수 안에서만 작동한다.
함수를 호출하고, 함수 본문이 실행되는 도중에 await를 사용한 줄에서 실행이 잠시 중단되었다가 Promise가 처리되면 실행이 재개된다.
await는 말 그대로 프라미스가 처리될 때까지 함수 실행을 기다리게 만든다.
프라미스가 처리되면 그 결과와 함께 실행이 재개된다.
프라미스가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
아래 코드를 보자. 1, 2, 3 순으로 출력되는 것이 아니라 1 3 2 순으로 출력이 된다!
await를 만나면 함수 본문을 잠시 멈추고 3을 먼저 출력한 다음 await가 처리되면 2를 출력한다!
async function promise() {
console.log(1)
data = await new Promise(resolve => {
resolve('duck');
});
console.log(2);
};
promise();
console.log(3);
//1 3 2
아래처럼 3을 출력하는 부분을 콜백함수로 만들어주면 정상적으로 1, 2, 3 순으로 출력이 된다!
then 부분이 마이크로 태스크 큐이고 setTimeout이 매크로 태스크 큐이기 때문이다!!
async function promise() {
console.log(1)
data = await new Promise(resolve => {
resolve('duck');
});
console.log(2);
};
promise();
setTimeout(() => {
console.log(3);
});
// 1 2 3
만약 아래처럼 async 함수 내부에서 변수를 사용해서 변수에 await의 결과 값을 할당하면 Promise의 resolve 값이 변수에 할당된다!!
.then()을 사용하는 것보다 훨씬 간편하지 않아?
async function promise() {
var data = await new Promise(resolve => {
resolve('duck');
});
console.log(data);
};
promise();
// duck
만약 async 함수 밖에서 변수를 선언하고 await의 결과값을 받고 출력하고 싶다면 어떻게 해야할까?
나는 처음에 아래와 같은 실수를 했다! 아래와 같이 코드를 data 변수에 값이 할당 되기 전에 data를 출력하는 부분이 먼저 실행되기 때문에 undefined가 출력된다!!
var data;
async function promise() {
data = await new Promise(resolve => {
resolve('duck');
});
};
promise();
console.log(data); //data를 할당하는 것보다 출력이 먼저 실행됨
//undefined
아래처럼 코드의 출력 부분을 콜백함수로 변경하면 원하는 결과값을 얻을 수 있다.
var data;
async function promise() {
data = await new Promise(resolve => {
resolve('duck');
});
};
promise();
setTimeout(() => {
console.log(data);
}, 0);
//duck
'Javascript > ES5 & ES6' 카테고리의 다른 글
빽틱 ` (0) | 2021.07.11 |
---|---|
Scope, =, 삼항연산자 (0) | 2021.07.07 |
비동기 패턴 - 콜백, Promise (0) | 2021.06.04 |
객체 생성, Class (0) | 2021.06.03 |
lodash (0) | 2021.06.02 |
주니어 개발자에욤
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!