Skip to content

Instantly share code, notes, and snippets.

@dlemfh
Last active July 3, 2021 05:25
Show Gist options
  • Save dlemfh/3fa360643d7ec0b9ba3c567287da2a1b to your computer and use it in GitHub Desktop.
Save dlemfh/3fa360643d7ec0b9ba3c567287da2a1b to your computer and use it in GitHub Desktop.

About JS Event Loop

  1. 실행되는 프로그램 전체는 하나의 task.

    (그 과정에서 발생하는 모든 call stack은 해당 task의 일부.)

  2. task 수행 도중 fs callback, setTimeout callback 등을 통해 task queue에 task를 추가할 수 있다.

    (종류에 상관 없이 task의 형태는 전부 callback function.)

  3. (task 수행 도중) resolve된 모든 promise에 대한 then/catch callback은 microtask queue에 추가된다.

  4. 한 task가 종료되었을 때 다음 task로 넘어가기 전, 먼저 microtask queue에서 모든 microtask가 고갈될 때까지 수행된다.


참고: async/await

  • 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
@dlemfh
Copy link
Author

dlemfh commented Jul 3, 2021

예제2

console.log('sync 1');

setTimeout(() => console.log('setTimeout 1'), 0);

const print = (x) => {console.log(x); return x;}

new Promise((resolve, reject) => {
        console.log('promise log');
        resolve('promise resolve');
}).then(print).then(print).then(print);

const f1 = async () => {
        console.log('f1 log');
        return 'f1 return';
};
f1().then(print);

f2().then(print);
async function f2() {
        console.log('f2 log');
        return 'f2 return';
}

setTimeout(() => console.log('setTimeout 2'), 0);

console.log('sync 2');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment