# 事件循环

# 同步任务与异步任务

// 同步任务
const a = () => console.log("a");
const b = () => console.log("b");
const c = () => {
  console.log("c");
  a();
  b();
};
c();

// c
// a
// b

// 掺杂异步任务
const a = () => console.log("a");
const b = () => console.log("b");
const c = () => {
  console.log("c");
  setTimeout(a, 0);
  b();
};
c();

// c
// b
// a

# 宏任务与微任务

ECMAScript 2015 引入了作业队列的概念,Pormise 使用了该队列,这种方式会尽快的执行异步函数的结果,而不是放在调用栈的末尾。
在当前函数结束之前,resolve 的 Promise 会在当前函数之后被立即执行(nextTick)

const a = () => console.log("a");
const b = () => console.log("b");
const c = () => {
  console.log("c");
  setTimeout(a, 0);
  new Promise((resolve, reject) => {
    resolve("应该在b之后,a之前");
  }).then((resolve) => console.log(resolve));
  b();
};
c();
// c
// b
// 应该在b之后,a之前
// a

常见的宏任务

I/O
setTimeout()
setInterval()
setImmediate() 相当于 setTimeout(()=>{}, 0)
requestAnimationFrame

常见的微任务

process.nextTick
Mutation Observer
Promise.then catch finally

# 了解 queueMicrotask()

queueMicrotask() - Web APIs | MDN (opens new window)

# 了解 process.nextTick()

每当事件循环进行一次完成的行程的时候,我们都将其成为一个滴答 TICK 当将一个函数传给 process.nextTick()时,则指示引擎在当前操作结束时调用此函数, example:

process.nextTick(() => {
  // do something
});

# 探索 JavaScript 定时器

setTimeout 一个典型的例子:

const fn = (a, b) => {};
setTimeout(fn, 2000, a, b);

setInterval 一个典型的例子:

const interval = setInterval(() + > {
    if (somethingFinished) {
        clearInterval(interval);
        return
    }
})

递归调用 setTimeout

const fn = () => {
  setTimeout(fn, 1000);
};
fn();