前言


以下内容是js在浏览器中的事件队列执行,与在nodejs中有所区别,请注意。

都说js是单线程的,不过它本身其实不是单线程,但是在浏览器中执行时只分配一个线程进行执行。

所以说js执行是单线程的,一次只能进行一项任务,就是一件任务一件任务做,做完一件做下一件。

认识一个栈两个队列


一个调用栈Stack。

一个宏队列,macrotask,也叫tasks。

一个微队列,microtask,也叫jobs。

执行过程


js就是执行全局Script同步代码,这中间碰到一些异步任务先加进对应的队列。

做完之后,调用栈就为空了。

然后将队列(先微队列后宏队列)里面的首个任务提到调用栈来做,一件一件做完直到队列中的任务都做完。

总结就是,先做同步的任务,再做微队列的任务,再做宏队列的任务。

异步任务怎么分配


这些异步任务包括但不限于:

以下分配给宏队列

setTimeout

setInterval

requestAnimationFrame

I/O

UI rendering

以下分配给微队列

Promise

Object.observe

MutationObserver

常见的宏队列:setTimeout,常见的微队列:Promise

简单例子


    console.log("同步任务1");

    setTimeout(() => {
console.log("宏任务");
}); new Promise((resolve, reject) => {
console.log("同步任务2");
resolve("微任务");
}).then((data) => {
console.log(data);
}); console.log("同步任务3");

结果是(按标号加任务,按箭头执行):



需要注意的是Promise的第一层没有执行回调之前是同步的,也就是上面的同步任务2

难一点的例子


    console.log("同步任务1");

    console.log("同步任务2");

    new Promise((resolve, reject) => {
console.log("同步任务3");
setTimeout(() => {
console.log("宏任务1");
Promise.resolve()
.then(() => {
console.log("微任务5");
})
.then(() => {
console.log("微任务6");
});
});
resolve("微任务1");
})
.then((data) => {
console.log(data);
return "微任务3";
})
.then((data) => {
console.log(data);
}); setTimeout(() => {
console.log("宏任务2");
}, 0); new Promise((resolve, reject) => {
resolve("微任务2");
})
.then((data, resolve) => {
console.log(data);
return "微任务4";
})
.then((data) => {
console.log(data);
}); console.log("同步任务4");

如何看呢,先看第一层,红色代表同步,绿色微任务,蓝色宏任务。

我们会把同步任务执行完,然后看见微任务有俩,宏任务也有俩。

本来的执行顺序可能是这样(我这里按照序号来表达顺序了,请和简单例子区分开来):



但是没那么顺利,执行到标号6时不一样了。

因为微任务执行过程中可能会产生新的微任务

上面的微任务1执行完会把微任务3加在微任务2后面,也就是微任务2执行完也轮不到宏任务,会继续执行新的微任务直到微任务队列暂时为空。

所以接下来会按照加入队列的顺序执行完四个微任务,这时候发现没有新的微任务产生,才开始执行宏任务:



但是需要注意的是,上面执行到标号5时又不一样了,宏任务一执行后又产生了新的微任务,所以宏任务两个并没有顺利连续执行,而是被插入的微任务拦住了。

要记住微任务与宏任务队列都存在时一定是微任务先执行完再来执行宏任务,即使是宏任务执行产生的微任务也同理



所以最后的答案,如果存在不理解的,可以在认真回顾一下上文:

js 在浏览器中的event loop事件队列的更多相关文章

  1. 浏览器中的 Event Loop

    当我们执行 JS 代码的时候其实就是往执行栈中放入函数,那么遇到异步代码的时候该怎么办?其实当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中.一旦执行栈为空, ...

  2. js的事件循环(Event Loop)

    (本文从掘金小册整理) 首先介绍一下几个概念 进程与线程 相信大家经常会听到 JS 是单线程执行的,但是你是否疑惑过什么是线程? 讲到线程,那么肯定也得说一下进程.本质上来说,两个名词都是 CPU 工 ...

  3. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?

    https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...

  4. [NodeJs系列][译]理解NodeJs中的Event Loop、Timers以及process.nextTick()

    译者注: 为什么要翻译?其实在翻译这篇文章前,笔者有Google了一下中文翻译,看的不是很明白,所以才有自己翻译的打算,当然能力有限,文中或有错漏,欢迎指正. 文末会有几个小问题,大家不妨一起思考一下 ...

  5. Node.js的事件轮询Event Loop原理

    Node.js的事件轮询Event Loop原理解释 事件轮询主要是针对事件队列进行轮询,事件生产者将事件排队放入队列中,队列另外一端有一个线程称为事件消费者会不断查询队列中是否有事件,如果有事件,就 ...

  6. 不要在nodejs中阻塞event loop

    目录 简介 event loop和worker pool event loop和worker pool中的queue 阻塞event loop event loop的时间复杂度 Event Loop中 ...

  7. Elasticsearch.js 发布 —— 在Node.js和浏览器中调用Elasticsearch(1)

    继PHP.Ruby.Python和Perl之后,Elasticsearch最近发布了Elasticsearch.js,Elasticsearch的JavaScript客户端库.可以在Node.js和浏 ...

  8. Elasticsearch.js 发布 —— 在Node.js和浏览器中调用Elasticsearch

    继PHP.Ruby.Python和Perl之后,Elasticsearch最近发布了Elasticsearch.js,Elasticsearch的JavaScript客户端库.可以在Node.js和浏 ...

  9. 浏览器和Node 中的Event Loop

    前言 js与生俱来的就是单线程无阻塞的脚本语言. 作为单线程语言,js代码执行时都只有一个主线程执行任务. 无阻塞的实现依赖于我们要谈的事件循环.eventloop的规范是真的苦涩难懂,仅仅要理解的话 ...

随机推荐

  1. python函数模块

    python函数模块 学习完本篇,你将会深入掌握 函数相关知识 1.函数定义 2.函数如何调用 3.递归函数以及匿名函数使用 模块相关知识 1.模块如何导入调用 2.函数调用顺序 函数定义 函数代码块 ...

  2. Python爬无止境,获得王者荣耀全部高清皮肤

    作为一名热爱王者两年的程序员,早就想爬取所有英雄皮肤的高清照片,在设个幻灯片放映,真香,这次只用16行代码就能实现,对于新手拿这个作为实战练手项目既简单又容易上手,快来尝试下. 百度"王者荣 ...

  3. PHP中的MySQLi扩展学习(六)MySQLI_result对象操作

    在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容.它的作用其实就是一个查询的结果集.不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查 ...

  4. P1088 [NOIP2004 普及组] 火星人

    题目描述 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学 ...

  5. IdentityServer4系列[6]授权码模式

    授权码模式是一种混合模式,是目前功能最完整.流程最严密的授权模式.它主要分为两大步骤:认证和授权.其流程为: 用户访问客户端,客户端将用户导向Identity Server. 用户填写凭证信息向客户端 ...

  6. ASP.NET Core中将Json字符串转换为JsonResult

    ASP.NET Core中返回JsonResult 最近在使用NET 5.0做WebApi中,发现只能返回string类型,不能用JsonResult返回实体,于是查阅资料找到解决办法. 两种方式分别 ...

  7. 详解package-lock.json的作用

    目录 详解package-lock.json package-lock.json的作用 版本号的定义规则与前缀对安装的影响 改动package.json后依旧能改变项目依赖的版本 当前项目的真实版本号 ...

  8. 运用shapefile.js解析Shp文件

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  9. Conversion Tools(转换工具)

    转换工具 1.Excel # Process: Excel 转表 arcpy.ExcelToTable_conversion("", 输出表, "") # Pr ...

  10. 使用Mybatis的一些基本配置及Mybatis与数据库交互测试验证

    1.简介 什么是MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.My ...