资讯专栏INFORMATION COLUMN

js基础进阶--promise和setTimeout执行顺序的问题

Integ / 1807人阅读

摘要:当主线程中的任务,都执行完之后,系统会依次读取任务队列里的事件。与之相对应的异步任务进入主线程,开始执行。结束资源地址基础进阶和执行顺序的问题博客地址如果您对我的博客内容有疑惑或质疑的地方,请在下方评论区留言,或邮件给我,共同学习进步。

欢迎访问我的个人博客:http://www.xiaolongwu.cn

前言

promise为es6引进的语言标准,为异步编程的一种解决方案;

阅读此文的前提是了解浏览器event loop的机制,还有promise的基本用法和特性,比如他自执行特性、状态不可逆特性等

抛出问题

且看下面代码和问题

setTimeout(function(){console.log(1)},0);
new Promise(function(resolve){
    console.log(2)
    for( var i=0 ; i<10000 ; i++ ){
        i==9999 && resolve()
    }
    console.log(3)
}).then(function(){
    console.log(4)
});
console.log(5);
// 这的问题是,为什么答案是 2 3 5 4 1
// 而不是 2 3 5 1 4

既然promise.then和setTimeout都是异步的,那么在事件循环队列中 promise.then的事件应该排在setTimeout后面,那为什么promise.then却在setTimeout前面被打印了出来?

重要概念

event loop 的概念

Javascript是单线程的,所有的同步任务都会在主线程中执行。

当主线程中的任务,都执行完之后,系统会 “依次” 读取任务队列里的事件。与之相对应的异步任务进入主线程,开始执行。

异步任务之间,会存在差异,所以它们执行的优先级也会有区别。大致分为 微任务(micro task,如:Promise、MutaionObserver等)和宏任务(macro task,如:setTimeout、setInterval、I/O等)。

Promise 执行器中的代码会被同步调用,但是回调是基于微任务的。

宏任务的优先级高于微任务

每一个宏任务执行完毕都必须将当前的微任务队列清空

第一个 script 标签的代码是第一个宏任务

主线程会不断重复上面的步骤,直到执行完所有任务。

我的理解

我们来捋一遍代码的执行过程,

所有的代码都写在script标签中,所以读取所有代码是第一个宏任务,我们开始执行第一个宏任务。

我们首先遇到setTimeout,他是第二个宏任务,将它扔进宏任务事件队列里先排队。

下来我们遇到promise,promise执行器里的代码会被同步调用,所以我们依次打印出2和3。

下来遇到promise的回调,他是一个微任务,将它扔进微任务事件对列中。

下来我们接着打印出5,然后执行微任务并且打印出4.

我们第一个宏任务执行完毕,执行下一个宏任务,打印出1,到此,所有任务都执行完毕。

所以我们最后的结果为2 3 5 4 1。

结束

github资源地址:js基础进阶--promise和setTimeout执行顺序的问题

csdn博客地址:https://blog.csdn.net/wxl1555

如果您对我的博客内容有疑惑或质疑的地方,请在下方评论区留言,或邮件给我,共同学习进步。

邮箱:wuxiaolong802@163.com

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

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

相关文章

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

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

    whjin 评论0 收藏0
  • 前端校招准备系列--jssetTimeout到底是什么?

    摘要:浏览器是多进程的,而浏览器的内核渲染进程是多线程的。如果已经将回调函数放进任务队列,但是主线程正在执行一个非常耗时的任务,当这个任务执行完毕后,主线程去任务队列中取任务,这个时候,就会出现连续执行的情况,也就是说相当于失效了。 前言   在刷笔试题的时候,经常会碰到setTimeout的问题,只知道这个是设置定时器;但是考察的重点一般是在一个方法中包含了定时器,定时器中的打印和方法中打...

    Godtoy 评论0 收藏0
  • JavaScript 进阶问题列表,你掌握了多少?

    摘要:在第四次调用时,回调函数依然没有返回值。累加器再次为,当前值为。 经常写业务就容易忽视对基础知识的补充和加强,但在面试中,基础知识点是非常重要的考核部分。本文要分享的是,一位开发者每天都会发布的 JavaScript 问题。有的容易,有的会有难度,对基础知识的查缺补漏非常有帮助,也是你进阶路上必然要掌握的知识。 以下挑选了10个问题,紧跟其后的就是对这道题的详细解答。如果你想看所有的题...

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

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

    chnmagnus 评论0 收藏0
  • JavaScript 事件机制

    摘要:的事件机制关于,查阅多篇博客,或多或少总有些出入,在此写下自己关于的理解按同步与异步分首先判断是同步还是异步同步就进入主进程异步就进入异步任务在中注册函数当满足触发条件后被推入同步任务进入主线程后一直执行直到主线程空闲时才会去中查看是否有可 JavaScript 的事件机制 关于Event Loop,查阅多篇博客,或多或少总有些出入,在此写下自己关于Event Loop的理解 按同步与...

    Turbo 评论0 收藏0

发表评论

0条评论

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