博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EventLoop
阅读量:6868 次
发布时间:2019-06-26

本文共 2191 字,大约阅读时间需要 7 分钟。

毋庸置疑,大家都很了解js是一门单线程语言,这也就说明JS无法进行多线程,但是JS中异步的功能完全可以模拟多线程,而且效果还杠杠滴。当然,如果想完全理解异步,首先要了解JS的运行核心——事件环(Event Loop),下面分两部分理解事件环:

一:浏览器中的事件环(Event Loop)

  1. 为了能更好的理解JS在浏览器中的任务队列和事件循环,请看下图:

  • eventLoop 是由JS的宿主环境(浏览器)来实现的;
  • 事件循环可以简单的描述为以下四个步骤:
1. 函数入栈,当Stack中执行到异步任务的时候,就将他丢给WebAPIs,接着执行同步任务,直到Stack为空;2. 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列)3. 执行栈为空时,Event Loop把微任务队列执行清空;4. 微任务队列清空后,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,回到第1步。复制代码
  1. 认识浏览器中的任务源(task):
  • 微任务:then 、messageChannel 、mutationObersve
  • 宏任务:setTimeout、setInterval、setTmmediate(只兼容ie)
  1. 下面实现一个小例子:
console.log(1);console.log(2);setTimeout(function () {  console.log('setTimeout1');  Promise.resolve().then(function () {    console.log('promise');  });});setTimeout(function () {  console.log('setTimeout2');});复制代码

打印结果:

1

2
setTimeout1

promise

setTimeout2

二:Node 环境中的事件环(Event Loop)

  1. 为了能更好的理解JS在Node环境中的任务队列和事件循环,请看下图:

  • 图虽然有些乱,但是我们只需关心timers计时器阶段和poll轮询阶段,check检查阶段即可,clons关闭阶段以及微任务队列即可。

  • Node 环境中微任务是插缝执行,(如果执行宏任务的时候发现了微任务, 不会像浏览器一样执行了,而是将为微任务放到微任务队列中,等待整个宏 任务队列执行完毕或者达到执行上线后,下一个阶段开始的时候先执行 完微任务队列中的任务)。

  1. 认识Node中的任务源(task):
  • 微任务: then 、nextTick 、 messageChannel 、mutationObersve
  • 宏任务:setTimeout 、setInterval 、setImmediate 、io文件操作
  1. 例一:timeout、immediate 两个谁先执行不一定 取决于node的执行时间。
setTimeout(function () {    console.log('setTimeout1');})setImmediate(function () {    console.log('setImmediate2');});复制代码
打印结果有两种:
  • 1) setTimeout1 setImmediate2
  • 2) setImmediate2 setTimeout1
  1. 例二: 如果i/o文件操作以后就会先执行setImmediate,因为setImmediate在i/o文件操作后面的那个阶段执行,执行完setImmediate会在下一个阶段的时候再执行setTimeout (timers 计时器执行阶段)
let fs = require('fs');fs.readFile('1.log', function () {  console.log('fs');  setTimeout(function () {    console.log('timeout');  });  setImmediate(function () {    console.log('mmiediate');  });});复制代码
打印顺序结果
  • fs 、 miediate、 timeout
  1. 例三: 微任务中nextTIck 会比then先执行。
Promise.resolve().then(function () {  console.log('then2'):});process.nextTick(function () {  console.log('nextTick1');});复制代码
打印顺序结果
  • nextTick1 then2
  1. 例四: 微任务会优先与i\o文件操作执行。
let fs = require('fs');fs.readFile('./1/log',function(){    console.log('fs')})process.nextTick(function(){    console.log('text2');})复制代码
打印执行结果
  • text2 fs

好了,今天就到这,如有错误,请下方留言。作为码农一枚,最大的愿望和最伟大的理想是,大宝天天见,bug死生不复相见,相忘于江湖,恩怨一笔消失!!!

转载地址:http://pedfl.baihongyu.com/

你可能感兴趣的文章
内核同步机制
查看>>
python 基础(格式化输出,初始编码,数据类型及其操作)
查看>>
重建二叉树
查看>>
Apache 虚拟主机 VirtualHost 配置
查看>>
asp.net mvc 小心Html.RenderAction
查看>>
Calendar类经常用法 日期间的转换 set方法有巨坑
查看>>
配置 Phpstorm + Xdebug + xampp
查看>>
初学HTC
查看>>
win7 VMware Workstation Centos6.5虚机桥接上网设置 详解(靠谱)
查看>>
消息队列
查看>>
p2114 起床困难综合症
查看>>
11.2、正则表达式Perl风格函数的应用
查看>>
《深入理解mybatis原理3》 Mybatis数据源与连接池
查看>>
C#返回两个日期之间的时间间隔
查看>>
BZOJ-4034: [HAOI2015]树上操作 (线段树+DFS序)
查看>>
maven下载jar包源码配置
查看>>
关于MYSQL通过子查询删除重复数据的for update报错问题解决
查看>>
进程与fork()、wait()、exec函数组
查看>>
ASP.NET入门(1) - 建立和开发ASP.NET 5 项目
查看>>
织梦内页读取栏目banner图
查看>>