闻心阁

一蓑烟雨看苍生,半壶浊酒笑红尘

浅说JavaScript之Event Loop(上)

2018-03-14 约 1 分钟读完 搬砖秘籍
Event Loop 也叫事件循环,是 JavaScript 中的基础概念,听起来蛮唬人,查了一些资料,斗胆用大白话来说说这个东西。PS:仅限浏览器的讨论。 为什么会有 Event Loop 这一切还要从 JavaScript 的诞生说起,因为造它的用途简单,就是来浏览器“谈谈心”。谈心嘛,套路什么的不用太深,给你一个单线程的脑子就够了。于是乎,这“一根筋”的 JavaScript 就来到了人间,虽然这个呆头呆脑的家伙后来上了一件叫 “Worker” 的装备,也开始学会了城里人的套路,但它总归是村里出来的(web worker本身限制诸多,有空再叨),再多的套路也没变了它“一根筋”的本质。 虽然它“一根筋”,但它不傻。不管工作多么忙碌,人家照样张弛有度。举例来说,就像衣服放洗衣机了,它才不会在那等着45分钟衣服洗完去晒,而是继续扫地、打麻将…等听到洗衣机洗完响了,再去收。它的这个本事就叫“非阻塞”,而让它能有这个本事的,就是今天的主角——Event Loop。 Event Loop 的流程 说起 Event Loop 的流程,要先看这张来自 Philip Roberts 的图。 基本的过程就先从左边看起,JavaScript 主线程运行的过程中产生了 堆(heap) 和 栈(stack),栈中的代码顺序执行,当遇到“拦路虎(异步)”操作的时候,就把这“锅”扔给浏览器老大哥,并对它说“大哥,这事我不好搞,你帮搞定吧。对了,搞定完了,和我弟(任务队列/task queue)说一声啊。”。然后继续栈中的代码跳过这,继续往下走,再遇到(比如DOM操作,AJAX请求)再找老大哥。。。 当栈中的活都干完了,“哎?大哥帮我把事处理的怎样了?找我弟问问去。” 老弟(任务队列)给了一个列表:二哥,这些活(回调),还要你干。 于是,把任务队列的活再接着干,直到没活可干,就可以休息了。 这就是上面图的流程,所以同步总要比异步的结果先出来。比如: setTimeout(function(){ console.log('2') }, 0) console.log('1') console.log('3') 结果: 1 3 2 老弟的账本(任务队列的秘密) 既然 JavaScript 这么信任小弟,那小弟做事也不能马虎,对浏览器老大哥也是言听计从。可老弟也是一个有原则的人。当浏览器老大哥给来一堆任务的时候,哪个在前,哪个在后呢? 老弟内心也门清,他把这些任务分为了2类,当官的(micro task)和老百姓(macro task)。任务来了,他就先看看身份,然后把他们放到不同的队伍中去(干部的纯洁性嘛)。于是当大任务(好处)来临时,干部优先嘛,先处理micro task,再处理macro task。 那何人可为官? new Promise() new MutaionObserver() 老百姓是谁? setInterval() setTimeout() 所以下面的代码: setTimeout(function () { console.log(1); }); new Promise(function(resolve,reject){ console. 继续阅读