# 事件循环
# 同步任务与异步任务
// 同步任务
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();