美文网首页
事件循环

事件循环

作者: wcmoon | 来源:发表于2019-11-27 22:39 被阅读0次

0. 为什么有事件循环

我们知道 JS 是单线程非阻塞执行的。单线程很好理解,可以避免多线程同时对某些资源操作时的混乱,比如多同一个 DOM 的操作等。那非阻塞的实现,就不可避免的要说到事件循环,事件循环在单线程上实现了异步的执行。

1. 执行栈和事件队列

首先说明两个概念。
第一个是执行栈。JS 的函数在执行时,会先在执行栈中加入执行的环境,也就是Context,也叫执行上下文。举个简单的例子:

(function foo(i) {
if (i === 3) {
return;
}
else {
foo(++i);
}
}(0));

上述代码中,每次调用 foo 函数,都会在执行栈中推入一个 context,其中每次的 i 都不同。然后在每一个环境被执行之后,就从栈中移除。
第二个是事件队列。当异步操作结束后,回调将被挂起,然后加入到事件队列,并继续执行当前执行栈中的环境。一直到当前执行栈中所有的任务被执行完,主线程处于空闲状态,则从事件队列中取出第一个事件,开始执行。

2. micro task 和 macro task

按照上面的说法,我们来看一段代码

setTimeout(()=>{console.log(1)}); 
new Promise(function(resolve, reject){
  console.log(2);
  resolve();
}).then(function(){
  console.log(3);
});

按照上面的说法,执行顺序应该是这样的:
开始事件队列为空,主线程闲置,将 setTimeout 押入执行栈,输出1;
然后执行 promise 内部代码,输出2;
紧接着执行 then 中传入的 resolve,输出3。
但是实际的输出是 2, 3 ,1。
这就涉及到另一个概念,就是 micro task 和 macro task。
事实上,当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。
这就可以解释了以上代码。

ps:

以上是在浏览器中的事件循环执行过程,在 node 中的执行会有所不同。

相关文章

  • 浅谈JavaScript事件循环与Vue的批量异步更新策略

    在介绍事件循环之前,首先要明确以下几个关键概念。事件循环,同步和异步任务,宏任务,微任务。 一.事件循环 事件循环...

  • 并发:事件循环 & asyncio

    1. 事件循环机制 1.1. 什么是事件循环 事件循环(Event Loop),即通过轮询方法监控事件; asyn...

  • 探索未知种族之osg类生物---呼吸分解之事件循环一

    事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环、更新循环以及渲染循环了。首先我们来区分一下事件循环和渲染循...

  • 事件循环

    先来一张图 下面上写的代码,在看浏览器的主线程的执行情况 再来上主线程页面初始化加载时的情况 setInterva...

  • 事件循环

    事件触发不会马上执行回调,会加入队列,队列中按照先进先出的顺序,逐个执行事件绑定的回调方法 新事件产生后会插在队尾...

  • 事件循环

    总结:第一次循环先执行宏任务中的队头任务,清空调用栈后执行微任务,然后第二次循环执行宏任务的队头任务,.........

  • 事件循环

    原文链接:https://zhuanlan.zhihu.com/p/26229293最近琢磨了好久的Javascr...

  • 事件循环

    单线程 .JavaScript是单线程javascript是单线程,无论后面加了什么标准,什么操作,都不能改变ja...

  • 事件循环。。

    Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。 Node.js 的每一个 A...

  • 事件循环

网友评论

      本文标题:事件循环

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