-
실행되는 프로그램 전체는 하나의 task.
(그 과정에서 발생하는 모든 call stack은 해당 task의 일부.)
-
task 수행 도중 fs callback, setTimeout callback 등을 통해 task queue에 task를 추가할 수 있다.
(종류에 상관 없이 task의 형태는 전부 callback function.)
-
(task 수행 도중) resolve된 모든 promise에 대한 then/catch callback은 microtask queue에 추가된다.
-
한 task가 종료되었을 때 다음 task로 넘어가기 전, 먼저 microtask queue에서 모든 microtask가 고갈될 때까지 수행된다.
- async 함수가 호출되어도 execution은 계속해서 해당 async 함수 안으로 진입한다.
- await는 해당 async 함수의 resolve 결과에 대해 then callback을 등록하는 syntactic sugar일 뿐.
async function f1() {
console.log('enter f1')
const result = await f2()
console.log('after f2')
// ...do something with result
}
async function f2() {
console.log('enter f2')
}
f1()
console.log('after f1')
f1()
호출 시 즉시 안으로 진입한다. (enter f1
출력.)await f2()
만났을 때도 즉시f2()
안으로 진입한다. (enter f2
출력.)f2()
의 return 값은 (undefined
이지만) Promise로 포장된다.f1()
으로 돌아온 후, await로 인해 (result에 assign하는 부분을 포함한) 이후 모든 코드가 하나의 큰 then callback으로 묶인다.- 해당 then callback은
f2()
를 포장한 Promise가 resolve되는 순간(= 위 코드의 경우 즉시) microtask queue에 추가된다. - CPU execution은 (await을 감싼 async 함수인)
f1()
다음으로 넘어간다. (after f1
출력.) - task 수행이 모두 끝나고, microtask queue에 들어가 있는 then callback이 수행된다. (
after f2
출력.)
요약)
- async 함수에 대한 호출이라도 그 즉시 수행.
const r = await f()
는return f().then((r) => {...})
과 같다.
async function f() {
console.log('f1')
await g();
console.log('f2')
}
async function g() {
console.log('g')
}
setTimeout(() => {console.log('task')}, 0)
console.log('before')
f();
console.log('after');
before
f1
g
after
f2
task
예제2