美文网首页
JavaScript异步机制

JavaScript异步机制

作者: pixels | 来源:发表于2016-10-21 15:12 被阅读91次

众所周知,JavaScript是单线程,同一时刻只会有一段代码在运行。JavaScript又具有异步的特性,这二者是否冲突呢。JavaScript又是怎样在单线程的情况下执行异步代码的呢?
  但凡单线程且具备异步特性的语言,都是event-driven(事件驱动)的,而驱动这个事件(event-handler)的平台即驱动平台。浏览器就是一个驱动平台,JavaScript虽然是单线程的,但是浏览器是多线程的,浏览器通过暴露给JavaScript一些API(WebAPI),来实现异步的功能。JavaScript里面常用到的setTimeout、Ajax、DOM Events就是WebAPI。
  浏览器有两个核心部分,渲染引擎和JavaScript引擎。JavaScript主线程执行时候,产生对和栈。JavaScript异步的实现过程描述如下:

  1. 程序中的代码一次进入栈,等待执行,执行完毕后出栈。
  2. 当执行到setTimeout等WebAPI时,将setTimeout方法压栈,浏览器内核的其他线程开始执行WebAPI的callback,setTimeout出栈。
  3. JavaScript主线程继续执行后续代码(完成进栈出栈的过程),同时浏览器处理callback方法,当callback达到触发条件时,方法被添加到任务队列。
  4. 栈中代码执行完毕后,主线程去查看任务队列中,是否有callback等待执行,如果有,将callback方法压入栈中,执行完毕后出栈。

以下代码

    alert(1);
    setTimeout("alert(2)", 0);
    for(var i = 3; i < 30; i++) {
      alert(i);
    }

运行,会发现,弹出1后并不会马上弹出2,而是先弹出3-30,然后在弹出2,按照以上介绍的异步实现过程可以,程序会先执行alert(1),然后执行setTimeout方法,setTimeout方法是WebAPI,所以浏览器的其他线程会处理callback,callback方法0秒后就被触发了,放入任务队列,但是此时,JavaScript后续代码还没有执行完毕,JavaScript主线程会继续执行后续代码至全部执行完毕,此时栈为空,主线程才会将堆中的callback方法压入栈中执行,所以setTimeout 0的callback不一定会0秒后执行。

以演讲中的示例进一步说明(转载地址
http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/#prettyPhoto

s1
s2
以图中代码为例,执行引擎开始执行上述代码时,相当于先讲一个main()方法加入执行栈。继续往下开始console.log('Hi')时,log('Hi')方法入栈,console.log方法是一个webkit内核支持的普通方法,而不是前面图中WebAPIs涉及的方法,所以这里log('Hi')方法立即出栈被引擎执行。
s3
s4
console.log('Hi')语句执行完成后,log()方法出栈执行,输出了Hi。引擎继续往下,将setTimeout(callback,5000)添加到执行栈。setTimeout()方法属于事件循环模型中WebAPIs中的方法,引擎在将setTimeout()方法出栈执行时,将延时执行的函数交给了相应模块,即图右方的timer模块来处理。
s5
执行引擎将setTimeout出栈执行时,将延时处理方法交由了webkit timer模块处理,然后立即继续往下处理后面代码,于是将log('SJS')加入执行栈,接下来log('SJS')出栈执行,输出SJS。而执行引擎在执行万console.log('SJS')后,程序处理完毕,main()方法也出栈。
s6
s7
s8

相关文章

  • JS notebook goods

    JS 机制 JavaScript异步机制 Excuse me?这个前端面试在搞事! JavaScript 运行机制...

  • js的事件循环

    javascript是一个单线程语言,javascript分为同步机制及异步机制,其中同步机制是放在栈中,而异步机...

  • 异步/回调

    单线程的JavaScript 说起异步,就要先说说JavaScript运行机制。我们知道,JavaScript是单...

  • Javascript异步机制

    Javascript作为一种单线程语言,是如何实现异步编程的呢? 相信不少人对Javascript单线程表示怀疑:...

  • JavaScript异步机制

    众所周知,JavaScript是单线程,同一时刻只会有一段代码在运行。JavaScript又具有异步的特性,这二者...

  • JavaScript异步机制

    最近在忙着写React源码系列,写到第四篇——React Fiber,这篇还需要好好研究下才能写(๑•ᴗ•๑),今...

  • ES6(7)之Async和await

    先谈JavaScript的异步处理 JavaScript是一门单线程的编程语言,如果不设计异步处理的机制,很容易因...

  • ES6 Promise

    问题 JavaScript的Callback机制深入人心。而ECMAScript的世界同样充斥的各种异步操作(异步...

  • JS异步编程(2)-异步核心Event loop

    Event loop 是 JavaScript 异步编程的核心,通过事件循环机制,让单线程的 JavaScript...

  • 且听前端大牛为你解析:Node.js内部捕获异步错误的步骤,看不

    一、背景 众所周知,由于 JavaScript 特殊的 EventLoop 机制,由 Promise 异步产生错误...

网友评论

      本文标题:JavaScript异步机制

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