资讯专栏INFORMATION COLUMN

promise与setTimeout的执行顺序问题

Alliot / 629人阅读

摘要:输出创建输出第一个过程过后,已经输出了第二步由于其他的优先级高于。此时中有两个任务按照优先级高于所以先输出,再输出第三步,任务列表已经执行完毕,家下来执行由于的优先级高于,所以先输出,再输出。

有一次在面试题中有做到promise与setTimeout的执行顺序,当时有点懵,执行顺序还是弄错了一点点,这里记录下
1.输出
setTimeout(function() {
    console.log(111)
}, 0);
setTimeout(function() {
    console.log(333)
}, 1000);
new Promise(function(resolve){
    console.log(444);
    resolve();
    console.log(555);
}).then(function(){
    console.log(666);
});
console.log(777);
async function test1() {
    console.log("test1");
    await test2();
    console.log("test1 last");
}
async function test2() {
    console.log("test2");
}
test1();

输出结果

2.个人理解

首先执行同步代码,然后以事件轮询的方式执行异步代码

promise中的异步体现在.then()和.catch()中

而promise中的function里的是同步代码

上面的代码是先执行promise里的同步代码,然后执行脚本里本身的同步代码

async无论方法是同步还是异步都可以用async关键字来进行标识

因为用async标识只是显示表明在该方法内,可能会用到await关键字使其变为异步方法,而且将该异步方法进行了明确的划分,只有用了await关键字时才是异步操作,其余一并为同步操作

同 Generator 函数一样,async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数

当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句

await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中

3.其他

在网上还找到了一些资料

参考了这篇文章的一些内容 参考文章
setImmediate(function(){
    console.log(1);
},0);
setTimeout(function(){
    console.log(2);
},0);
new Promise(function(resolve){
    console.log(3);
    resolve();
    console.log(4);
}).then(function(){
    console.log(5);
});
console.log(6);
process.nextTick(function(){
    console.log(7);
});
console.log(8);

输出结果: 3 4 6 8 7 5 2 1

macro-task: script (整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering. 
micro-task: process.nextTick, Promise(原生),Object.observe,MutationObserver

第一步. script整体代码被执行,执行过程为

创建setImmediate macro-task
创建setTimeout macro-task
创建micro-task Promise.then 的回调,并执行script console.log(3); resolve(); console.log(4); 此时输出3和4,虽然resolve调用了,执行了但是整体代码还没执行完,无法进入Promise.then 流程。
console.log(6)输出6
process.nextTick 创建micro-task
console.log(8) 输出8 

第一个过程过后,已经输出了3 4 6 8

第二步. 由于其他micro-task 的 优先级高于macro-task。

此时micro-task 中有两个任务按照优先级process.nextTick 高于 Promise,所以先输出7,再输出5

第三步,micro-task 任务列表已经执行完毕,家下来执行macro-task. 由于setTimeout的优先级高于setIImmediate,所以先输出2,再输出1。

优先级: promise.Trick()>promise的回调>setTimeout>setImmediate

正在努力学习中,若对你的学习有帮助,留下你的印记呗(点个赞咯^_^)

往期好文推荐:

判断iOS和Android及PC端

纯css实现瀑布流(multi-column多列及flex布局)

实现多行文字及单行的省略号

微信小程序之购物车和父子组件传值及calc的注意事项

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108748.html

相关文章

  • 用一道大厂面试题带你搞懂事件循环机制

    本文涵盖 面试题的引入 对事件循环面试题执行顺序的一些疑问 通过面试题对微任务、事件循环、定时器等对深入理解 结论总结 面试题 面试题如下,大家可以先试着写一下输出结果,然后再看我下面的详细讲解,看看会不会有什么出入,如果把整个顺序弄清楚 Node.js 的执行顺序应该就没问题了。 async function async1(){ console.log(async1 start) ...

    ShowerSun 评论0 收藏0
  • 一道setTimeout async promise执行顺序笔试题引发思考

    摘要:如果你要问他和谁当进去的快,要从下面两个方面考虑结束时。至于什么,查了很多的资料,了解到一个浏览器环境只能有一个事件循环,而一个事件循环可以有多个任务队列。 ====据说这是今日头条去年的一道笔试题,主要考察的是setTimeout async promise执行顺序 ~先双手奉上这道题目~ async function async1() { consol...

    soasme 评论0 收藏0
  • JavaScript执行顺序分析

    摘要:每个线程的任务执行顺序都是先进先出在运行的环境中,有一个负责程序本身的运行,作为主线程另一个负责主线程与其他线程的通信,被称为线程。主线程继续执行我是第一主线程执行完毕,从线程读取回调函数。 前言 上星期面试被问到了事件执行顺序的问题,想起来之前看《深入浅出Node.js》时看到这一章就忽略了,这次来分析一下JavaScript的事件执行顺序。废话少说,正题开始。 单线程JavaScr...

    chnmagnus 评论0 收藏0
  • 夯实基础-JavaScript异步编程

    摘要:调用栈被清空,消息队列中并无任务,线程停止,事件循环结束。不确定的时间点请求返回,将设定好的回调函数放入消息队列。调用栈执行完毕执行消息队列任务。请求并发回调函数执行顺序无法确定。 异步编程 JavaScript中异步编程问题可以说是基础中的重点,也是比较难理解的地方。首先要弄懂的是什么叫异步? 我们的代码在执行的时候是从上到下按顺序执行,一段代码执行了之后才会执行下一段代码,这种方式...

    shadowbook 评论0 收藏0
  • 前端基础进阶(十二):深入核心,详解事件循环机制

    摘要:前端基础进阶正是围绕这条线索慢慢展开,而事件循环机制,则是这条线索的最关键的知识点。特别是中正式加入了对象之后,对于新标准中事件循环机制的理解就变得更加重要。之后全局上下文进入函数调用栈。 showImg(https://segmentfault.com/img/remote/1460000008811705); JavaScript的学习零散而庞杂,因此很多时候我们学到了一些东西,但...

    whjin 评论0 收藏0

发表评论

0条评论

Alliot

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<