前段时间在网上陆续看了很多关于 Event loop 的文章,看完也就混个眼熟,可能内心深处对这种偏原理的知识有一些抵触心情,看完后也都没有去深入理解。最近在看 Vue 的源码,在读到关于 nextTick 的实现时,总有一种似曾相识的感觉,于是去网上查了下资料,原来 nextTick 的实现正是基于 Event loop 机制(引起重视了)。

Call Stack

众所周知,JavaScript 是 one-threaded,也就意味着在执行 JavaScript 的过程中,是 One thing at a time,而这样的特性,正是由一个叫 Call Stack 的东西决定的(有且仅有一个)。
既然是栈,就满足 FILO 的原则。故 Call Stack 在函数运行时的表现为:

  • 当有函数执行时,该函数被 push 到 Call Stack
  • 当函数执行结束时,该函数从 Call Stack 内被 pop 出
  • 如果函数内有调用到其他函数(执行结束前),则将其他函数再 push 到 Call Stack 中,等到调用结束时 pop 出

由此可见,如果一个函数定义如下:

const dead = () => {return dead();
}

那么当其被执行时,就会向 Call Stack 中不断的 push 同一个函数(dead),导致整个页面挂掉。

When Call Stack Meets Sync Request

众所又周知了,在 jQuery 提供的 Ajax 函数中,可供开发者选择请求是 sync 还是 async,我们先讨论 Call Stack 遇到 sync 请求时会发生什么。

const name = $.ajaxSync(URL_1);
const info = $.ajaxSync(URL_2);
const work = $.ajaxSync(URL_3);console.log(name);
console.log(info);
console.log(work);

屋漏偏逢连阴雨,此时的网络状态又极差,每一个网络请求从发出到成功要经历五秒,想象一下上面这段代码如果跑起来了,会发生什么?
这是一件让人绝望的事情:
随着程序的推进,ajaxSync 函数会先后三次被 push 并 pop 出 Call Stack,而每一次从 push 到 pop 的过程需要耗费五秒钟的时间。
无论从工程效率还是用户体验的角度来说,这都是不被允许的一件事情。

Async & Callback

为了杜绝上面的问题,浏览器提供给了开发者一个叫做异步 Callback 的解决方案。先看一段代码:

console.log('kyrieliu');setTimeout(function(){console.log('about Event Loop');
}, 5000);console.log(' is writing an article ');

运行结果显而易见。
ok,那么这段代码在 Call Stack 中的表现又是怎样的呢?
基于上面文章所述,我推测:
首先,第一行代码入栈,执行完毕后出栈;紧接着,setTimeout 入栈,然后emmm,事情有点不对劲了:如果 setTimeout 入栈执行后立刻出栈,那么它内部的 console 为什么五秒后才打印出来?

Task Queue

问题的关键,是一个叫做 Task Queue 的东西。
紧接着刚才的步骤:setTimeout入栈后执行并触发了一个五秒的 timer,这个 timer 由 Web api 维护,至此,setTimeout执行完毕并出栈,第三个 console 入栈执行并出栈。五秒后,timer 结束计时,将回调函数 callback 下放到 task queue 中。
但 callback 还未执行,它什么时候执行呢?Call Stack 为空的时候。
此时的 call stack 已经为空,所以 callback 被 push 进栈执行并 pop 出,这样一来就解释得通了。 至此,正式引出 Event Loop 的概念。

Event Loop

If the call stack is clear and there's something in the task queue, push the first thing on the queue onto the stack.

setTimeout(callback, 0)

在最开始接触 JavaScript 的时候,看到上面这行代码的我是懵蔽的,0ms 后执行 callback, WTF?
在了解了 Event Loop 的运行机制后,再回过头来尝试解释一下这行代码,即:在 setTimeout 入栈执行时,内部的 callback 会立即被下放到 task queue 中,但它无法执行,因为此时的 call stack 不为空,等到 call stack 为空时,callback 才得以执行。

Thanks

  • Philip Roberts: Help, I’m stuck in an event-loop.
  • A super-cool demo of Event Loop

广而告之

个人公众号,不止于前端


Event Loop 其实也就这点事相关推荐

  1. 正确理解javascript中的Event loop机制

    这两个星期一直在想着写一篇关于javascript中event Loop的文章.自从写完上一篇<Javascript捕捉(capturing)与冒泡(bubbling)的区别>之后,我抛出 ...

  2. 从Promise来看JavaScript中的Event Loop、Tasks和Microtasks

    原文 github.com/creeperyang- 主题 Promise 看到过下面这样一道题: (function test() {setTimeout(function() {console.l ...

  3. 跟着 Event loop 规范理解浏览器中的异步机制

    原文发自我的 GitHub blog,欢迎关注 前言 我们都知道 JavaScript 是一门单线程语言,这意味着同一事件只能执行一个任务,结束了才能去执行下一个.如果前面的任务没有执行完,后面的任务 ...

  4. JavaScript 运行机制详解:Event Loop

    转自: http://www.ruanyifeng.com/blog/2014/10/event-loop.html 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单 ...

  5. Node.js event loop 和 JS 浏览器环境下的事件循环的区别

    Node.js  event loop 和 JS 浏览器环境下的事件循环的区别: 1.线程与进程: JS 是单线程执行的,指的是一个进程里只有一个主线程,那到底什么是线程?什么是进程? 进程是 CPU ...

  6. 不要在nodejs中阻塞event loop

    文章目录 简介 event loop和worker pool event loop和worker pool中的queue 阻塞event loop event loop的时间复杂度 Event Loo ...

  7. 【朴灵评注】JavaScript 运行机制详解:再谈Event Loop

    PS: 我先旁观下大师们的讨论,得多看书了~ 别人说的:"看了一下不觉得评注对到哪里去,只有吹毛求疵之感. 比如同步异步介绍,本来就无大错:比如node图里面的OS operation,推敲 ...

  8. 第七期:详解JavaScript运行机制(Event Loop)

    在浏览器中,每个渲染进程都有一个主线程,主线程非常繁忙,既要处理DOM,又要计算样式,还要处理布局,同时还需要处理JavaScript任务以及各种输入事件.此时我们就需要一个系统来统筹调度这么多不同类 ...

  9. 运行指定代码_JavaScript 运行机制(Event Loop)详解

    一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...

最新文章

  1. uni-app 封装企业微信config
  2. 练习一下linux中的list函数。
  3. 如何用python进行量化交易_从零开始学习Python和量化交易
  4. 在目标检测被“遗忘”领域进行探索后,百度开源最新力作UMOP:即插即用、无痛涨点
  5. 【dfs】家族(jzoj 1985)
  6. 企业内容管理-互联网应用
  7. Redux学习(一)——Redux的使用过程
  8. mac下antlr4命令使用
  9. 这样的 Spring Cloud 微服务项目太牛了!
  10. 7. HTTP 请求,响应
  11. 【bzoj1022】[SHOI2008]小约翰的游戏John 博弈论
  12. Android混淆和加固详解
  13. 雾芯科技,创新者的窘境
  14. linux根文件系统树制作
  15. SAR图像聚焦质量评价插件
  16. centos 中 Discuz 论坛模板配置问题
  17. 编码器SRT协议三种模式(listener, caller, rendezvous)简介
  18. 输出1000以内能被7整除又能被5整除的数
  19. 网络游戏是如何开发的?
  20. 从学生到机器视觉工程师,我有话要说!

热门文章

  1. 输入法问题_「图」KB4515384再爆新问题:OOBE时中文输入法阻止创建本地账户
  2. php json追加500错误,在composer.json中添加了一个git地址;composer update 报错
  3. si9000阻抗匹配计算_如何在设计之初计算出两层PCB板差分线的阻抗,线宽,间距...
  4. 服务器选购seo优化规则,网站seo优化注意事项1—域名和服务器选择
  5. springcloud服务注册和发现
  6. 201771010112罗松《面向对象程序设计(java)》第三周学习总结
  7. 利用 %20 替换 空格
  8. 向其他进程注入代码的三种方法
  9. CC++初学者编程教程(8) VS2013配置编程助手与QT
  10. ubuntu 编译 /usr/bin/ld: cannot find 问题解决