本来标题是 ‘[学习笔记] Promise, async/await, setTimeout的输出顺序’, 结果因为限制长度太长就改成现在这个标题…
1. 事件循环, 微任务,宏任务
要弄清楚 Promise,async/await, setTimeout() 这三者函数体内的输出顺序, 首先要了解他们在事件循环中扮演的角色
异步任务:
- 微任务: Promise(), async/await
- 宏任务: setTimeout(), setInterval(), Ajax请求, DOM事件
事件循环简要流程:
(注: 微任务是ES6规定的, 为了执行微任务, ES6再专门规定一个micro task queue来执行微任务, 而宏任务是浏览器规定的, 放进Callback queue)
- 执行同步代码,一行一行放进Call stack里面执行
- 遇到异步任务先"记录",
- 当Call stack里面的同步任务执行完之后,在"记录"下来的异步任务里面寻找微任务
- 将微任务 (Promise, async/await) 放进 micro task queue 中, 然后push进Call stack执行
- 当微任务执行完毕后,尝试进行DOM渲染
- 最后触发事件循环机制,将异步任务里面的宏任务调出放进Callback queue
- 按顺序push进Call stack 执行代码
2. Promise() ,async/await, setTimeout() 的输出顺序
了解完事件循环过程后, 来看Promise() ,async/await, setTimeout() 的输出顺序:
**数字代表输出顺序
//注意:即使async/await是异步任务的微任务(按照事件循环机制,同步代码完成后执行微任务), 但是
// 实际上async里面的await后面执行的代码才是异步, 所以如果遇到async函数直接作为同步跳进去执行
async function async1 () {
console.log('async1 start') // 2 这里仍是同步
await async2() // 这一句也会同步执行,正常应返回Promise对象, 但是async2()只有一行console.log('async2').所以这里返回的是undefined,
//而其中的 `console.log('async2')` 也会同步执行
console.log('async1 end') // 上面有 await, 这里就变成了“异步”,作为第一个微任务"记录"下来,类似 callback 的功能(微任务) //6
}
async function async2 () {
console.log('async2') //3
}
console.log('script start') // 第一个同步代码直接输出 1
setTimeout(function () { // 异步,宏任务
console.log('setTimeout') //8
}, 0)
async1()
new Promise (function (resolve) { // 返回 Promise 之后,仍作为同步执行完成,直到then之后才是异步代码, 和await相似
console.log('promise1') // Promise 的函数体会立刻执行 4
resolve()
}).then (function () { // 异步,作为第二个微任务"记录"下来
console.log('promise2') // 7
})
console.log('script end') //5 !!到这里结束所有同步代码,开始执行异步任务
结果输出:
- script start
- async1 start
- async2
- promise1
- script end
- async1 end
- promise2
- setTimeout
如有任何错误,欢迎大家指出,一起学习!!!!!!感谢
本文探讨了JavaScript中的事件循环机制,详细解释了微任务(如Promise和async/await)与宏任务(如setTimeout)的执行顺序。在事件循环过程中,同步代码执行完成后,会先处理微任务,然后才执行宏任务。通过一个示例展示了Promise、async函数和setTimeout的输出顺序,帮助读者深入理解这一关键概念。
678

被折叠的 条评论
为什么被折叠?



