美文网首页
单线程异步和event-loop

单线程异步和event-loop

作者: 变态的小水瓶 | 来源:发表于2019-03-08 18:22 被阅读0次

单线程异步

js是单线程异步的,单线程就是同一时间只做一件事,原因是避免dom操作的冲突,设想一下js是多线程的,然后多线程上的js都要操作一个dom,就会产生冲突。而仅仅是单线程的话,如果有一个请求要耗费很长时间时,浏览器就会卡在那里等待,这样当然也不行,所以有了异步。

event-loop

那么异步要怎么运行?这就是接下来要说的event-loop(事件轮询)
event-loop是js的运行机制,其执行的方式如下:

image.png

1.同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
2.当指定的事情完成时,Event Table会将这个函数移入Event Queue。
3.主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
4.上述过程会不断重复,也就是常说的Event Loop(事件循环)。

除了广义的同步任务和异步任务,我们对任务有更精细的定义:

macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick

注意:任务队列分微任务和宏任务,先执行全部的微任务,再执行宏任务。

接下来看一下下面的案例:

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');
}, 0);
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
  }).then(function() {
    console.log('promise2');
  });
console.log('script end');

分析:

1、整个代码块作为一个宏任务,进入主线程,async1和async2函数定义,遇到console.log输出script start;
2、遇到setTimeout() ,把它的回调函数放入宏任务(setTimeout1)。

微任务 宏任务
setTimeout1

3、遇到执行async1(), 执行async1,遇到console.log输出async1 start;
4、然后遇到await async2(),执行async2();
5、看到console.log输出async2,之后没有返回值,结束函数,返回undefined,返回到async1的执行上下文的await undefined,由于async函数使用await后得语句会被放入一个回调函数中,所以把下面的放入微任务中。

微任务 宏任务
async1=> await后面的语句 setTimeout1

6、结束async1,返回全局上下文,遇到Promise构造函数,里面的执行函数立马执行, 输出promise1, 之后的回调函数进入微任务;

微任务 宏任务
async1=> await后面的语句 setTimeout1
new Promise() => 后的then

执行完Promise(),遇到console.log,输出script end,这里一个宏任务代码块执行完毕。

7、主线程现在空闲下来后,执行事件队列中的微任务,遇到new Promise()后面的回调函数,执行代码,输出promise2(这里2个微任务的优先级,promise高于async)。

8、看到async1中await后面的回调函数,执行代码,输出async1 end

9、此时微任务中的队列为空,开始执行队列中的宏任务,遇到console.log,输出setTimeout。
最后,执行完成,最后结果为

script start 
async1 start 
async2
promise1
script end 
promise2 
async1 end
setTimeout

参考文章:
https://juejin.im/post/59e85eebf265da430d571f89

相关文章

  • JS异步方案

    JS异步方案 单线程和event-loop callback jquery的deferred promise as...

  • 异步的那些事(一)

    单线程,event-loop,异步,promise,async await 这些名词在js中经常被提及。然而他们之...

  • 单线程异步和event-loop

    单线程异步 js是单线程异步的,单线程就是同一时间只做一件事,原因是避免dom操作的冲突,设想一下js是多线程的,...

  • event-loop 【js】

    单线程 单线程:同一时间只能做一件事 原因:避免DOM渲染冲突 解决方案:异步 实现方式:event-loop e...

  • 单线程/异步/事件轮询(event-loop)

    1.单线程 只有一个线程,同一时间只能做一个事情,JS代码需要一行行执行,不是多行执行 --------单线程 只...

  • js事件机制与Promise

    (ps:不对之处,敬请指正!!!) Event-Loop 众所周知,JavaScript是单线程的,不知是哪个天才...

  • Dart与消息循环机制[翻译]

    翻译自https://www.dartlang.org/articles/event-loop/ 异步任务在Dar...

  • js的单线程和异步

    js的单线程和异步 js是一直是单线程的,浏览器才是实现异步的那个家伙

  • Promise入门详解和基本用法

    异步调用 异步 JavaScript的执行环境是单线程。 所谓单线程,是指JS引擎中负责解释和执行JavaScri...

  • JavaScript异步编程

    目录 JavaScript采用单线程模式工作的原因 单线程的优势和弊端 同步模式与异步模式同步模式异步模式同步模式...

网友评论

      本文标题:单线程异步和event-loop

      本文链接:https://www.haomeiwen.com/subject/ugldpqtx.html