我们都知道javascript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步

一、同步和异步

所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就是同步任务,比如简单的逻辑操作及函数,而异步任务不会立马立马执行,会挪步放到到异步队列中,比如ajax、promise、事件、计时器等等。

也就是先执行同步,主线程结束后再按照异步的顺序再次执行。

二、时间循环(Event Loop)

Event Loop是什么?中文翻译是事件循环,等待主线程中任务全部完成后,再回来把异步队列中任务放到主程序中运行,这样反复的循环,就是事件循环。

先来看组代码

console.log('开始111');

setTimeout(function() {

console.log('setTimeout111');

}, 0);

Promise.resolve().then(function() {

console.log('promise111');

}).then(function() {

console.log('promise222');

});

console.log('开始222');

我们猜想一下上面的代码,会怎样打印?我们知道,肯定是先走同步的代码,从上往下,先打印 “开始111”,再打印“开始222”。
中途的三个异步,进入到了异步队列,等待同步执行完(打印完),返回来再执行异步,所以是后打印出来。
打印的结果先放一放,我们稍后回来再说。现在我们中途插播一段知识点:

三、宏观任务和微观任务(先执行微观任务,再执行宏观任务):

在事件循环中,每进行一次循环操作称为tick,tick 的任务处理模型是比较复杂的,里边有两个词:分别是 Macro Task (宏任务)和 Micro Task(微任务)。

简单来说:

宏观任务主要包含:setTimeout、setInterval、script(整体代码)、I/O、UI 交互事件、setImmediate(Node.js 环境)

微观任务主要包括:Promise、MutaionObserver、process.nextTick(Node.js 环境)

规范:先执行微观任务,再执行宏观任务

那么我们知道了,Promise 属于微观任务, setTimeout、setInterval 属于宏观任务,先执行微观任务,等微观任务执行完,再执行宏观任务。所以我们再看一下这个代码:

console.log('开始111');

 
setTimeout(function() {
 
  console.log('setTimeout111');
 
}, 0);
 
Promise.resolve().then(function() {
 
  console.log('promise111');
 
}).then(function() {
 
  console.log('promise222');
 
});
 
console.log('开始222');
 

我们按照步骤来分析下:

1、遇到同步任务,直接先打印 “开始111”。
2、遇到异步 setTimeout ,先放到队列中等待执行。
3、遇到了 Promise ,放到等待队列中。
4、遇到同步任务,直接打印 “开始222”。
5、同步执行完,返回执行队列中的代码,从上往下执行,发现有宏观任务 setTimeout 和微观任务 Promise ,那么先执行微观任务,再执行宏观任务。

所以打印的顺序为: 开始111 、开始222 、 promise111 、 promise222 、 setTimeout111 。

同理,我们再来分析一个代码:

console.log('开始111');

setTimeout(function () {

console.log('timeout111');

});

new Promise(resolve => {

console.log('promise111');

resolve();

setTimeout(() => console.log('timeout222'));

}).then(function () {

console.log('promise222')

})

console.log('开始222');

分析一下:

1、遇到同步代码,先打印 “开始111” 。
2、遇到setTimeout异步,放入队列,等待执行 。
3、中途遇到Promise函数,函数直接执行,打印 “promise111”。
4、遇到setTimeout ,属于异步,放入队列,等待执行。
5、遇到Promise的then等待成功返回,异步,放入队列。
6、遇到同步,打印 “开始222”。
7、执行完,返回,将异步队列中的代码,按顺序执行。有一个微观任务,then后的,所以打印 “promise222”,再执行两个宏观任务 “timeout111” “timeout222”。

所以,打印的顺序为:开始111 、 promise111 、 开始222 、 promise222 、 timeout111 、 timeout222 .

先执行主任务,把异步任务放入循环队列当中,等待主任务执行完,再执行队列中的异步任务。异步任务先执行微观任务,再执行宏观任务。一直这样循环,反复执行,就是事件循环机制。

js 彻底搞懂事件循环机制 Event Loop的更多相关文章

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

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

  2. js事件循环机制(Event Loop)

    javascript从诞生之日起就是一门  单线程的  非阻塞的  脚本语言,单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务,非阻塞靠的就是 event lo ...

  3. js高级-浏览器事件循环机制Event Loop

    JavaScript 是队列的形式一个个执行的 同一时间只能执行一段代码,单线程的  (队列的数据结构) 浏览器是多线程的 JavaScript执行线程负责执行js代码 UI线程负责UI展示的 Jav ...

  4. 初探nodejs事件循环机制event loop

    nodejs的特点 nodejs 具有事件驱动和非阻塞I/O的特点. 事件驱动是指nodejs把每一个任务当成事件来处理. 非阻塞I/O是指nodejs遇到I/O任务时,会从线程池调度单独的线程处理I ...

  5. 关于事件循环机制event loop

    setTimeout(()=> { console.log('settimeout') },100) console.log('开始') console.log('结束') new Promis ...

  6. js--事件循环机制

    前言 我们知道JavaScript 是单线程的编程语言,只能同一时间内做一件事,按顺序来处理事件,但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这又是为什么呢?本文来总结一下js 的事件 ...

  7. Node.js 事件循环(Event Loop)介绍

    Node.js 事件循环(Event Loop)介绍 JavaScript是一种单线程运行但又绝不会阻塞的语言,其实现非阻塞的关键是“事件循环”和“回调机制”.Node.js在JavaScript的基 ...

  8. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  9. 深入理解JavaScript的事件循环(Event Loop)

    一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为 因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) ...

随机推荐

  1. Linux安装JAVA并且配置环境

    在写之前我先说一下我遇到的坑,我在配置环境的时候由于/etc/profile文件没有配置好导致系统彻底坏掉 1.ls vi等等命令使用不了,报错说找不到命令 2.在重启后虚拟机不能进入桌面 1.下载j ...

  2. Adaboost算法的一个简单实现——基于《统计学习方法(李航)》第八章

    最近阅读了李航的<统计学习方法(第二版)>,对AdaBoost算法进行了学习. 在第八章的8.1.3小节中,举了一个具体的算法计算实例.美中不足的是书上只给出了数值解,这里用代码将它实现一 ...

  3. Ceph实现数据的'不拆分'

    前言 之前看过一个朋友一篇文章,讲述的是Vsan为什么使用的是两副本,而ceph则大多数情况下需要三副本,当时个人观点是这个并不是关键点,但是在仔细考虑了问题的出发点以后,这个也可以说是其中的一个点 ...

  4. modprobe: FATAL: Module ceph not found解决办法

    问题 有可能你在进行 Ceph 文件系统挂载的时候出现下面的提示: modprobe: FATAL: Module ceph not found. mount.ceph: modprobe faile ...

  5. ceph单机多mon的实现

    ceph默认情况下是以主机名来作为mon的识别的,所以这个情况下用部署工具是无法创建多个mon的,这个地方使用手动的方式可以很方便的创建多个mon 1.创建mon的数据存储目录 mkdir /var/ ...

  6. CSS属性(字体与文本属性)

    1.字体属性 (1)font-family 把要对这个网站要设置的字体都写上,如果这个浏览器支持第一个字体,则会用,如果不支持则会尝试第二个,如果设置的字体系统都不支持则会使用系统默认的字体作为网站的 ...

  7. [原题复现]BJDCTF2020 WEB部分全部解

    简介  原题复现:https://gitee.com/xiaohua1998/BJDCTF2020_January  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学 ...

  8. 真的可惜,四面阿里,结果我被JVM垃圾回收机制与 OOM异常卡住了

    前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...

  9. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  10. Mac电脑疑似中毒该怎么应对处理

    Mac电脑作为相对封闭的一个系统,它会中毒吗?如果有一天Mac电脑产生了疑似中毒或者遭到恶意不知名攻击的现象,那又应该如何从容应对呢?这些问题都是小编使用Mac系统一段时间后产生的疑惑,通过一番搜索研 ...