JavaScript是单线程的编程语言,只能同一时间内做一件事。但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这就是因为JS有事件循环机制。

事件循环流程总结

  1. 主线程开始执行一段代码, 假设开始执行一个 script 标签内的代码,将代码放入执行栈中执行,同步代码优先执行,执行过程中,当遇到任务源时,判断是宏任务还是微任务。
  2. 如果是宏任务,加入到宏任务队列中,如果是微任务,加入到微任务队列中。
  3. 同步代码执行完成,执行栈空闲,检查微任务队列中是否有可执行任务,如果有,依次执行所有微任务队列中的任务。如果没有。当前任务执行结束。
  4. 渲染UI。
  5. 检查宏任务队列是否有可执行的宏任务,如果有,取出队列中最前面的那个宏任务,加入到执行栈中开始执行,然后重复前面步骤,直到宏任务队列中所有任务执行结束。

async/await执行顺序

我们知道async隐式返回 Promise 作为结果的函数,那么可以简单理解为,await后面的函数执行完毕时,await会产生一个微任务(Promise.then是微任务)。
 
但是我们要注意这个微任务产生的时机,它是执行完await之后,直接跳出async函数,执行其他代码(此处就是协程的运作,A暂停执行,控制权交给B)。
 
其他代码执行完毕后,再回到async函数去执行剩下的代码,然后把await后面的代码注册到微任务队列当中。

示例

// 今日头条面试题
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
} async function async2() {
console.log('async2')
} console.log('script start') setTimeout(function () {
console.log('settimeout')
}) async1() new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('promise2')
}) console.log('script end') // 'script start' => 'async1 start' => 'async2' => 'promise1' => 'script end' => 'async1 end' => 'promise2' => 'settimeout'
const p = Promise.resolve();

(async () => {
await p;
console.log('await end');
})(); p.then(() => {
console.log('then 1');
}).then(() => {
console.log('then 2');
});
// 'then 1' => 'then 2' => 'await end'
// 1. 开始执行

console.log(1)     // 2. 打印 1

setTimeout(function () {    // 6. 浏览器在 0ms 后,将该函数推入任务队列
console.log(2) // 7. 打印 2
Promise.resolve(1).then(function () { // 8. 将 resolve(1) 推入任务队列 9. 将 function函数推入任务队列
console.log('ok') // 10. 打印 ok
})
}) // 3.调用 setTimeout 函数,并定义其完成后执行的回调函数 setTimeout(function () { // 11. 浏览器 0ms 后,将该函数推入任务队列
console.log(3) // 12. 打印 3
}) // 4. 调用 setTimeout 函数,并定义其完成后执行的回调函数 // 5. 主线程执行栈清空,开始读取 任务队列 中的任务 // output: 1 2 ok 3

 

javaScript 事件循环机制的更多相关文章

  1. 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)

    JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...

  2. javascript事件循环机制 浅尝手记

    引入 众所周知Javascript是一个单线程的机制,虽然可以依托多线程的浏览器实现页面如何实现页面复杂的渲染.事件响应,但仍不会改变其单线程的本质:所以对于js的事件循环机制的了解是一个前端人员的必 ...

  3. 深入理解JavaScript事件循环机制

    前言 众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心.可看HTML规范中的这段话: To ...

  4. 深入浅出Javascript事件循环机制

    一.JS单线程.异步.同步概念 众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了-所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下.web ...

  5. 浏览器中的JavaScript事件循环机制

    浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...

  6. JS JavaScript事件循环机制

    区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...

  7. JavaScript事件循环机制

    事件循环 事件循环不仅仅包含事件队列,而是具有至少两个队列,除了事件,还要保持浏览器执行的其他操作.这些操作被称为任务,并且分为两类:宏任务(或通常称为任务)和微任务. 单次循环迭代中,最多处理一个宏 ...

  8. 一道面试题引发对javascript事件循环机制(Event Loop)的 思考(这里讨论针对浏览器)

  9. JS浏览器事件循环机制

    文章来自我的 github 博客,包括技术输出和学习笔记,欢迎star. 先来明白些概念性内容. 进程.线程 进程是系统分配的独立资源,是 CPU 资源分配的基本单位,进程是由一个或者多个线程组成的. ...

随机推荐

  1. 使用argparse进行调参

    argparse是深度学习项目调参时常用的python标准库,使用argparse后,我们在命令行输入的参数就可以以这种形式python filename.py --lr 1e-4 --batch_s ...

  2. 关于TornadoFx和Android的全局配置工具类封装实现及思路解析

    原文地址: 关于TornadoFx和Android的全局配置工具类封装实现及思路解析 - Stars-One的杂货小窝 目前个人开发软件存在设置页面,可以让用户自定义些设置,但我发现,存储数据的代码逻 ...

  3. 服务器安装mysql遇到的坑

    服务器安装mysql遇到的坑 一.CentOS7安装MySQL 1.下载:MySQL官方的 Yum Repository wget -i -c http://dev.mysql.com/get/mys ...

  4. mybatis中二级缓存整合ehcache实现分布式缓存

    mybatis自带二级缓存,但是这个缓存是单服务器工作,无法实现分布式缓存.那么什么是分布式缓存呢?假设现在有两个服务器1和2,用户访问的时候访问了1服务器,查询后的缓存就会放在1服务器上,假设现在有 ...

  5. mysql 开启binlog日志,恢复误删的表、数据、mysql库

    linux下开启mysql的binlog日志功能 1.配置mysql配置文件my.cnf(内容如下). #配置文件储存的位置log-bin=mysql-bin#5.7以及以上版本需要配置这一行(保证唯 ...

  6. 慢到不能忍?别忍了,Ubuntu 21.10 APT 源修改为华为云镜像源

    更新记录 2022年4月15日:本文迁移自Panda666原博客,原发布时间:2021年3月29日. 2022年4月15日:将源改为华为云,华为云更方便.Ubuntu从20.04更新到21.10. 切 ...

  7. python中 OS模块中 os.path.join() 函数用法简介

    基础用法 os.path.join() 用于拼接文件的路径,可以传入多个待拼接的路径 若各个路径之间不存在 " / ", 则其会自动为各个路径之间增加连接符 " / &q ...

  8. Ubuntu远程桌面助手(URDC)

    目前自动驾驶域控制器项目中使用了英伟达的Orin芯片+Ubuntu20.04系统.域控属于典型的Headless设备,开发调试时需要连接显示器(HDMI/DP).鼠标和键盘,或者使用NoMachine ...

  9. Java注解和反射

    1.注解(Annotation) 1.1.什么是注解(Annotation) 注解不是程序本身,可以在程序编译.类加载和运行时被读取,并执行相应的处理.注解的格式为"@注释名(参数值)&qu ...

  10. 3D可视化解决方案为巷道工程安全护航

    最近山东栖霞笏山金矿事故中被困22名矿工的生命安全,在揪着全国民的心.大家都在祈求他们能从井下活着回来. 正是由于被困矿工的坚韧意志和政府相关部门不眠不休的奋力营救,11名矿工终于在被困十余日后平安升 ...