🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
这题主要是考察这三者在事件循环中的区别,事件循环中分为宏任务队列和微任务队列。 * 其中settimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行; * promise.then里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行; * async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行。 ### 1. setTimeout ~~~js console.log('script start') //1. 打印 script start setTimeout(function(){ console.log('settimeout') // 4. 打印 settimeout }) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数 console.log('script end') //3. 打印 script start // 输出顺序: ->script start ->script end ->settimeout ~~~ ### 2. Promise Promise本身是**同步的立即执行函数**, 当在executor中执行resolve或者reject的时候, 此时是异步操作, 会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行,打印p的时候,是打印的返回结果,一个Promise实例。 ~~~js console.log('script start') let promise1 = new Promise(function (resolve) { console.log('promise1') resolve() console.log('promise1 end') }).then(function () { console.log('promise2') }) setTimeout(function(){ console.log('settimeout') }) console.log('script end') // 输出顺序: ->script start ->promise1 ->promise1 end ->script end ->promise2 ->settimeout ~~~ 当JS主线程执行到Promise对象时, * promise1.then() 的回调就是一个 task * promise1 是 resolved或rejected: 那这个 task 就会放入当前事件循环回合的 microtask queue * promise1 是 pending: 这个 task 就会放入 事件循环的未来的某个(可能下一个)回合的 microtask queue 中 * setTimeout 的回调也是个 task ,它会被放入 macrotask queue 即使是 0ms 的情况 ### 3. async/await ~~~js async function async1(){ console.log('async1 start'); //2 await async2(); console.log('async1 end') //5 } async function async2(){ console.log('async2') //3 } console.log('script start'); //1 async1(); console.log('script end') //4 // 输出顺序: ->script start ->async1 start ->async2 ->script end ->async1 end ~~~ async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。 举个例子: ~~~js async function func1() { return 1 } console.log(func1()) ~~~ ![](https://img.kancloud.cn/4a/a8/4aa839e81a22014e9a06d424dcfc97fd_408x102.png) 很显然,func1的运行结果其实就是一个Promise对象。因此我们也可以使用then来处理后续逻辑。 ~~~js func1().then(res => { console.log(res); // 30 }) ~~~ await的含义为等待,也就是 async 函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。await通过返回一个Promise对象来实现同步的效果。 ## 摘自 [ setTimeout、Promise、Async/Await 的区别](https://www.muyiy.cn/question/async/8.html) [JS 的执行机制](https://www.kancloud.cn/freya001/web-knowledge/703311) [JS Event Loop 和 Microtask Macrotask](https://github.com/FoooooooF/FrontEnd-Knowledge-Point/blob/master/kernel/event_loop.md)