资讯专栏INFORMATION COLUMN

【16】winter重学前端 - JavaScript执行(一):Promise里的代码为什么比se

Vicky / 2140人阅读

摘要:即使耗时一秒的执行完毕,再的,仍然先于执行了,这很好地解释了微任务优先的原理。把整个代码分割成了个宏观任务,这里不论是秒还是秒,都是一样的。

js实现异步的几种形式

回调函数

事件监听 - 事件驱动模式

发布/订阅 - 观察者模式

Promises对象

js异步历史

一个 JavaScript 引擎会常驻于内存中,它等待着我们把JavaScript 代码或者函数传递给它执行

在 ES3 和更早的版本中,JavaScript 本身还没有异步执行代码的能力,引擎就把代码直接顺次执行了,这个任务也就是宿主发起的任务。

在 ES5 之后,JavaScript 引入了 Promise,这样,不需要浏览器的安排,JavaScript 引擎本身也可以发起任务了。

宏观和微观任务

宏观任务:宿主发起的任务,每次的一段js代码执行过程,其实都是一个宏观任务(可大致理解为:宏观任务的队列就相当于事件循环)- 宿主级别

微观任务:JavaScript 引擎发起的任务 - JS 引擎级别

关系:每个宏观任务中维护一个微观任务队列 - 宏观任务中,JavaScript 的 Promise 还会产生异步代码,JavaScript 必须保证这些异步代码在一个宏观任务中完成

例子

Promise 永远在队列尾部添加微观任务

setTimeout 等宿主 API,则会添加宏观任务

执行顺序:

微观任务:在所属的宏观任务队列所有同步任务执行完成之后执行

宏观任务:宏任务的触发规则和调用次序

eg:执行一个耗时 1 秒的 Promise。
即使耗时一秒的 c1 执行完毕,再 enque 的 c2,仍然先于 d 执行了,这很好地解释了微任务优先的原理。

    setTimeout(()=>console.log("d"), 0)
  var r1 = new Promise(function(resolve, reject){
      resolve()
  });
  r.then(() => { 
      var begin = Date.now();
      // 强制了 1 秒的执行耗时,这样,我们可以确保任务 c2 是在setTimeout d后加入任务队列
      while(Date.now() - begin < 1000);
      console.log("c1") 
      new Promise(function(resolve, reject){
          resolve()
      }).then(() => console.log("c2"))
  });

事件循环

定义:JavaScript 引擎等待宿主环境分配宏观任务,在操作系统中,通常等待的行为都是一个事件循环 - 就是反复“等待 - 执行”

功能:判断循环是否结束、宏观任务队列等逻辑

如何分析异步执行的顺序:

首先我们分析有多少个宏任务;

在每个宏任务中,分析有多少个微任务;

根据调用次序,确定宏任务中的微任务执行次序;

根据宏任务的触发规则和调用次序,确定宏任务的执行次序;

确定整个顺序。

eg:
setTimeout 把整个代码分割成了 2 个宏观任务,这里不论是 5 秒还是 0 秒,都是一样的。
第一个宏观任务中,包含了先后同步执行的 console.log(“a”); 和 console.log("b")
setTimeout 后,第二个宏观任务执行调用了resolve,然后 then 中的代码异步得到执行,所以调用了 console.log(“c”),最终输出的顺序才是a,b,c

    function sleep(duration) {
        return new Promise(function(resolve, reject) {
            console.log("b");
            setTimeout(resolve,duration);
        })
    }
    console.log("a");
    sleep(5000).then(()=>console.log("c"));


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

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

相关文章

  • 重学前端学习笔记(十七)--Promise里的代码什么setTimeout先执行

    摘要:版本以及之前,本身还没有异步执行代码的能力,宿主环境传递给引擎,然后按顺序执行,由宿主发起任务。采纳引擎术语,把宿主发起的任务称为宏观任务,把引擎发起的任务称为微观任务。基本用法示例的回调是一个异步的执行过程。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的...

    pinecone 评论0 收藏0
  • 重学前端学习笔记(十七)--Promise里的代码什么setTimeout先执行

    摘要:版本以及之前,本身还没有异步执行代码的能力,宿主环境传递给引擎,然后按顺序执行,由宿主发起任务。采纳引擎术语,把宿主发起的任务称为宏观任务,把引擎发起的任务称为微观任务。基本用法示例的回调是一个异步的执行过程。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的...

    zorpan 评论0 收藏0
  • 重学前端学习笔记(十七)--Promise里的代码什么setTimeout先执行

    摘要:版本以及之前,本身还没有异步执行代码的能力,宿主环境传递给引擎,然后按顺序执行,由宿主发起任务。采纳引擎术语,把宿主发起的任务称为宏观任务,把引擎发起的任务称为微观任务。基本用法示例的回调是一个异步的执行过程。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的...

    xiongzenghui 评论0 收藏0
  • 重学前端学习笔记(九)--JavaScript中的对象分类

    摘要:固有对象由标准规定,随着运行时创建而自动创建的对象实例。普通对象由语法构造器或者关键字定义类创建的对象,它能够被原型继承。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱:ka...

    ShowerSun 评论0 收藏0

发表评论

0条评论

Vicky

|高级讲师

TA的文章

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