一个很好的练习事件循环的网站 https://www.jsv9000.app/
JS 将 异步任务 分为宏任务和微任务
1. 同步代码(js 执行栈/回调栈)
2. 微任务的异步代码(js 引擎)
- Process.nextTick(node)
- Promise.then() catch()
Promise 本身同步,then 和 catch 的回调函数是异步的微任务
- Async/Await
- Object.observe 等等
3. 宏任务的异步代码(宿主环境-浏览器、Node)
- script(代码块)
- Ajax/Fetch
- setTimeout/setInterval
- setImmediate
同步代码->微任务->宏任务
例子
例子 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| console.log(1); setTimeout(function () { console.log(2); }, 0);
const p = new Promise((resolve, reject) => { console.log(3); resolve(1000); console.log(4); });
p.then((data) => { console.log(data); });
console.log(5);
|
打印结果:1 3 4 5 1000 2
例子 2
1 2 3 4 5 6 7 8 9 10 11 12
| new Promise((resolve, reject) => { resolve(1); new Promise((resolve, reject) => { resolve(2); }).then((data) => { console.log(data); }); }).then((data) => { console.log(data); });
console.log(3);
|
打印结果: 3 2 1
例子 3
1 2 3 4 5 6 7 8 9 10 11 12
| console.log(11); setTimeout(() => { console.log(12); let p = new Promise((resolve) => { resolve(13); }); p.then((res) => { console.log(res); }); console.log(15); }, 0); console.log(14);
|
打印结果: 11 14 12 15 13
例子 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| setTimeout(() => { console.log(1); }, 0);
new Promise((resolve) => { console.log(2); resolve("p1"); new Promise((resolve) => { console.log(3); setTimeout(() => { resolve("setTimeout2"); console.log(4); }, 0); resolve("p2"); }).then((data) => { console.log(data); }); setTimeout(() => { resolve("setTimeout1"); console.log(5); }, 0); }).then((data) => { console.log(data); }); console.log(6);
|
打印结果:2 3 6 p2 p1 1 4 5
例子 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } console.log("script start");
setTimeout(() => { console.log("setTimeout"); }, 0); async1();
|
await async2();后面的代码的代码属于微任务
打印结果: script start 、 async1 start 、 async2 、async1 end 、setTimeout