浏览器工作原理学习(十五)

news/2024/7/8 1:48:05

微任务与宏任务

  1. 宏任务
  • 为了协调任务在主线程上执行,页面进程引入消息队列和事件循环机制,渲染进程内部会维护多个消息队列,主线程从这些任务队列中取出任务执行,这写消息队列种的任务称为宏任务。
  1. 微任务
  • 第一种:把异步回调函数封装成一个宏任务,添加到消息队列尾部,当循环系统执行到该任务的时候执行回调函数。
  • 第二种:在主函数执行结束后,当前宏任务结束之前执行回调函数,这通常都是以微任务形式体现。
  • 本质是:微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前。
  • 每个宏任务都关联了一个微任务队列。
  • 微任务的产生,MutationObserver监控某个DOM节点,然后再通过JS来修改。当DOM节点发生变化时,就会产生DOM变化记录的微任务;使用Promise时也会产生微任务。
  • 微任务执行过程中产生新的微任务不会推迟到下个宏任务中执行,而是在当前的宏任务中继续执行。
  • 通过异步操作解决了同步操作的性能问题,通过微任务解决了实时性的问题。

Promise的使用

  • Promise 通过回调函数延迟绑定和回调函数返回值穿透的技术,解决了循环嵌套。
  • Promise对象的错误具有冒泡性质,会一直象后传递,直到被onReject函数处理或catch语句捕获为止。
  • Promise的onResolve需要延时调用,因此和微任务挂钩。
  • 回调地狱:下一任务依赖上个任务的结果,并在上个任务的回调函数内部执行新的业务逻辑,这样当嵌套层次过多后,代码的可读性变差。
  • Promise回调函数的延时绑定:先创建Promise对象,通过Promise的构造函数executor来执行业务逻辑,创建好Promise对象之后,在使用 then()来设置回调函数。
  • Promise 将回调函数 onResolve的返回值穿透至最外层:Promise执行结果会保存在promise的data变量中,然后是.then方法返回值为使用resolve或rejected回调方法新建的一个promise对象。即例如成功则返回new Promise(resolved),将前一个promise的data值赋值给新建的promise。
  • Promise内部有resolved_和rejected_变量保存成功和失败的回调,进入.then(resolved,rejected)时会判断rejected参数是否为函数,若是函数,错误时使用rejetcted处理错误;若不是,则错误是直接throw错误,一直传递到最后的捕获,若最后没有捕获,则会报错。

async/await:使用同步的方式去写异步代码

  1. 生成器(Generator)是如何工作的?
  • 生成器函数是一个带星号函数,而且是可以暂停执行和恢复执行的。
  • 在生成器函数内部执行一段代码,如果遇到yield关键字,那么js引擎将返回关键字后面的内容给外部,并暂停该函数的执行。
  • 外部函数可以通过next方法恢复函数的执行。
  • 协程:是一种比线程更加轻量级的存在。你可以把协程看成是跑在线程上的任务,一个线程上可以存在多个协程,但是在线程上同时只能执行一个协程。
  • 协程不是被操作系统内核所管理,而完全由程序所控制,线程间的切换不会消耗太多资源。通过yield关键字交出主线程控制权同时js引擎会保存当前协程的调用栈信息,并切换到父协程的调用栈,通过next()时JS引擎会保存当前的调用栈信息,并将切换到协程调用栈,通过returen关键字关闭协程。
  • 生成器就是协程的一种实现方式,协程和Promise相互配合执行的一个大致流程,把执行生成器的代码封装成一个函数,并把这个执行生成器代码的函数称为执行器(co框架)
  1. async/await
  • async/await技术背后的秘密就是Promise和生成器应用,往底层就是微任务和协程应用
  • async是一个通过异步执行并隐式返回Promise作为结果的函数。
  • await 默认创建一个Promise对象,然后通过微任务执行,最后通过Promise回调函数将值透传至最外层。

async function foo() {
    console.log('foo')
}
async function bar() {
    console.log('bar start')
    await foo()
    console.log('bar end')
}
console.log('script start')
setTimeout(function () {
    console.log('setTimeout')
}, 0)
bar();
new Promise(function (resolve) {
    console.log('promise executor')
    resolve();
}).then(function () {
    console.log('promise then')
})
console.log('script end')

1. 首先在主协程中初始化异步函数foo和bar,碰到console.log打印script start;
2. 解析到setTimeout,初始化一个Timer,创建一个新的task
3. 执行bar函数,将控制权交给协程,输出bar start,碰到await,执行foo,输出foo,创建一个 Promise返回给主协程
4. 将返回的promise添加到微任务队列,向下执行 new Promise,输出 promise executor,返回resolve 添加到微任务队列
5. 输出script end
6. 当前task结束之前检查微任务队列,执行第一个微任务,将控制器交给协程输出bar end
7. 执行第二个微任务 输出 promise then
8. 当前任务执行完毕进入下一个任务,输出setTimeout

http://www.niftyadmin.cn/n/2608618.html

相关文章

django markdown

1. 编辑器 css 1 <link rel"stylesheet" href"{% static plugin/editor.md/css/editormd.css %}"> div 1 <div id"editormd" class"col-md-10 text-left"> 2 <textarea name&…

浏览器工作原理学习(十六)

请求陷入排队的几种情况 页面中的资源是有优先级的&#xff0c;比如CSS、HTML、JS等哦都是页面中的核心文件&#xff0c;所以优先级最高。而图片、视频、音频这类资源就不是核心资源&#xff0c;优先级就比较低&#xff0c;通常当后者遇到前者时&#xff0c;就需要让路&#x…

tidb 架构 ~Tidb学习系列(1)

一 简介:今天来研究Tidb 二 安装测试: 0 下载Tidb wget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz 按如下步骤依次启动PD, TiKV, TiDB 1 启动pd 这里如果无法启动,大概率是2379端口被占用,极大可能是redis服务 nohup ./bin/pd-server --data-dirpd --lo…

在CentOS-6.9里安装openvswitch-2.5.4

第一步&#xff1a;安装依赖yum install rpm-build openssl-devel gcc wgetyum install python-devel kernel-devel kernel-debug-devel libtool第二步&#xff1a;下载包wget -O /root/rpmbuild/SOURCES/openvswitch-2.5.4.tar.gz http://openvswitch.org/releases/openvswitc…

浏览器工作原理学习(十七)

显示器是如何显示图像的 每个显示器都有固定的刷新频率&#xff0c;通常是60HZ&#xff0c;也就是每秒更新60张图片&#xff0c;更新的图片都来自于显卡中一个叫前缓冲区的地方&#xff0c;显示器就是每秒固定读取60次前缓冲区中的图像&#xff0c;并将读取的图像显示到显示器…

第八讲---mysql 5.6 order by limit 排序分页数据重复问题

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a; 上个月&#xff0c;部门同事发现了代码中的一个bug&#xff0c;就是在分页查询的时候使用order by limit&#xff0c;由于order by后面没有加索引&#xff0c;所以查出来的数据会出现重复的问题。这个是…

浏览器工作原理学习(十八)

DOM的缺陷 JS操作DOM时会影响到整个渲染流水线的。DOM提供了一组JS接口用来遍历或者修改节点&#xff0c;这会引发重排或者重绘。强制同步布局和布局抖动问题也大大降低渲染效率。复杂的页面&#xff0c;DOM结构也就复杂&#xff0c;没触发一次重排或者重绘都是非常耗时的。 …

微信分享和钉钉分享的设置

在天猫超级粉丝日的H5制作中需要同时能分享到钉钉和微信。见代码 在html的head中加入 //钉钉 <script type"text/javascript" src"https://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script> //微信 <script type"tex…