前言今天是学习EventLoop的时候了。其实之前写过一篇关于EventLoop的文章:JS中EventLoop事件循环浅析(初学者)是JS系列动态图里面的,可以结合之前的文章~我们都知道JavaScript是一个单-线程语言:同一时间只能运行一个任务。通常这很好,但是如果您有一个需要30秒的任务,是否所有其他任务都必须等待30秒?(由于JS运行在浏览器主线程,30秒内整个页面会卡住)好在浏览器提供了一些JS引擎没有的功能:WebAPI。它包括DOMAPI、setTimeout、HTTP请求等。这些特性可以帮助我们处理异步的、非阻塞的操作。调用堆栈当我们调用一个函数时,它会被添加到称为调用堆栈的东西中,它是JS引擎的一部分,而不是特定于浏览器的。本质上它是一个具有后进先出(LIFO)特点的栈。当函数调用完成时,它会从调用堆栈中弹出。上图中的response函数返回了一个setTimeout函数,这个函数也被添加到调用栈中,(setTimeout只是WebAPI提供的函数之一:它允许我们在不阻塞主线程的情况下延迟任务的执行。)setTimeout被调用后,将传递给它的箭头函数()=>{return'嘿'}添加到WebAPI中(这里简化概念,详见作者另一篇文章)。同时,setTimeout和respond函数从调用堆栈中弹出,它们都返回相应的值。任务队列在WebAPI中,已经创建了一个定时器,它会等待1000ms,当时间到了,这个箭头函数不会立即被调用栈执行,它会被加入到一个队列中,我们称之为它是一个任务队列(原文叫CallbackQueue)。这里可能会让人疑惑:回调箭头函数在1000ms后并不是直接加入到调用栈中,而是加入到任务队列中。排队,就是大家排队,先到先得,谁来服务?这是正确的!它是调用堆栈。说了这么多事件循环,终于轮到我们的事件循环了!如果说上面的调用栈是银行窗口,任务队列中的回调函数是排队做生意的人,那么EventLoop就是调用系统!EventLoop的唯一任务就是连接任务队列和调用栈:它不断检查调用栈中是否有任务需要执行。如果没有,它会检查任务队列,从中弹出一个任务,并将其放入调用堆栈,等等。上图中,终于轮到箭头函数接受调用了。调用之后,也弹出来了。它轻轻地走了,只留下一声嘿!o(╯□╰)o举个例子。很容易理解~我们来看一个例子,你可以将下面的代码粘贴到浏览器控制台并自己运行:constfoo=()=>console.log("First");constbar=()=>setTimeout(()=>console.log("第二"),500);constbaz=()=>console.log("第三");bar();foo();baz();我们称函数为bar。bar返回一个setTimeout函数。setTimeout中的回调函数添加到WebAPI中,从调用栈中弹出setTimeout函数和bar调用完成。计时器启动,同时函数foo被调用,打印出First。foo函数返回未定义。函数baz被调用,打印Third。500ms定时器结束,回调函数被放入任务队列,EventLoop检查调用栈是否为空,所以取出并放入调用栈。执行回调函数,打印出Second。全文就到这里了,希望对大家理解EventLoop有所帮助~本文为系列译文:动态图形JavaScript:提升动态图形JavaScript:作用域链(ScopeChain)动态图形JS:事件循环(EventLoop)【本文】DynamicGraphicsJS:JavaScriptEngineDynamicGraphicsJS:PrototypeInheritance
