Promise、Async\Await、setTimeout的执行顺序
2020-03-09 23:13
781 查看
先来看一道经典面试题
转载(https://juejin.im/post/5b03e79951882542891913e8)
async function async1(){ console.log('async1 start') await async2() console.log('async1 end') } async function async2(){ console.log('async2') } console.log('script start') setTimeout(function(){ console.log('setTimeout') },0) async1(); new promise(function(resolve){ console.log('promise1') resolve(); }).then(function(){ console.log('promise2') }) console.log('script end')
弄明白执行顺序要掌握的知识点
- JS事件循环机制
- Promise(阮老师:http://es6.ruanyifeng.com/#docs/promise)
- Async\Await(阮老师:http://es6.ruanyifeng.com/#docs/async)
- 异步任务(微任务、宏任务)[ 微任务优先于宏任务执行 ]
以下事件属于宏任务:
setInterval() setTimeout()
以下事件属于微任务
new Promise() new MutaionObserver()
我的理解
*JS是单线程,所以浏览器再解析上面那段代码的时候会自上往下解析,因此 第一输出:script start, 接着继续往下执行,这时会遇到 setTimeout() ,js会将该函数放入任务队列的宏任务队列。 接着继续往下执行,遇到 async1(),执行 async1() 函数 第二输出:async1 start, 继续往下执行,遇到 await async2() ,此时会先返回一个属于async1() 的Promise对象,并且会放入微任务队列 接着执行async2(),该函数也是一个 async 函数,所以也会返回一个Promise 对象,并且会放入微任务队列* 第三输出:async2 如果疑惑输出 async2 后为什么不接着输出 async1 end? 因为 async 函数遇到 await 会先返回,得等到await后面的异步任务执行完才会执行后面的语句。具体看阮老师写的ES6 到此异步任务结束,继续往下执行,遇到 new Promise() 该函数会立即执行,因此 第四输出:promise1 继续往下执行,遇到 resolve() 函数,该函数是回调函数,所以放入微任务队列,,.then()也是回调,放入微任务队列。 继续往下执行,遇到 console.log('script end')。 第五输出:script end 此时主线程都执行完毕,然后去异步任务队列调用异步任务,但是要遵循两个原则: 微任务优先宏任务、先进先出。 因此:先执行 async1() 函数返回的Promise对象,因为没又返回值,所以什么也不会打印。 再执行 async2() 函数返回的Promise对象,同样什么也不打印。 第六输出:async1 end 然后再去找 new Promise() 返回的 Promise 对象,执行. then() 方法, 第七输出:promise2 第八输出:setTimeout setTimeout 属于宏任务,因此最后输出。
总结
由于js是单线程,因此浏览器中 js引擎 在解析 js代码 的时候默认会自上而下解析,如果遇到异步事件(setTimeout、ajax等)会分类放入对应的异步任务队列(Event Loop)中,等主线程上同步程序都执行完毕,主线程会去异步任务队列中按照规则找出异步事件并执行。
正确的执行顺序script start、async1 start、async2、promise1、script end、async1 end、promise2、setTimeout
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 关于async/await、promise和setTimeout执行顺序
- setTimeout、promise、async/await执行顺序引发的对宏观任务和微观任务的理解
- 详解promise、async和await的执行顺序
- 8张图让你一步步看清 async/await 和 promise 的执行顺序
- promise、async、await之执行顺序
- promise、async和await执行顺序
- setTimeout与console.log、promise.then之间执行先后顺序
- setTimeout async promise执行顺序总结
- 高级之路篇十八:setTimeout、Promise、async、await
- js基础进阶--promise和setTimeout执行顺序的问题
- promise与setTimeout的执行顺序问题
- 用async-await实现类似Promise.all()的执行效果
- ReactNative踩坑日志——使用async/await语法解决网络请求的异步导致的指令执行顺序错乱问题
- “setTimeout、Promise、Async/Await 的区别”题目解析和扩展
- 使用Promise和async-await实现的一个异步遍历+同步执行任务的实例
- js中setTimeout与Promise执行顺序
- 错误的理解引起的bug async await 执行顺序
- “setTimeout、Promise、Async/Await 的区别”题目解析和扩展
- setTimeout async promise执行顺序总结
- promise.then,process.nextTick, setTimeout 以及 setImmediate 的执行顺序