美文网首页
Javascript的异步编程的理解

Javascript的异步编程的理解

作者: kallsaver | 来源:发表于2017-01-05 22:54 被阅读0次

在单线程的javascript编程来说,所有的任务分为两种,一种是同步任务(synchronous),

另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,

才能执行后一个任务,异步任务指的是,不进入主线程,而进入"任务队列"(task queue)的任务,

只有"任务队列"通知主线程,某个异步任务就可以执行了,该任务才会进入主线程执行。

具体来说就是:

1.所有的同步任务都在主线程上执行,形成一个执行栈(execution context stack)

2.主线程之外,还存在一个"任务队列"(task queue),只要异步任务有了运行结果,就在"任务队列"之中放置一个事件

3.一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。

那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行

4.主线程不断重复上面的第三步

只要主线程空了,就会读取"任务队列",这就是javascript的运行机制,这个过程会不断重复

Event Loop 是上面的第三步 这个过程是不断重复的

可以参考:

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

setTimeout(function(){console.log(1);}, 0);

console.log(2);

上面代码的执行结果总是2,1,因为只有在执行完第二行以后,

系统才会去执行"任务队列"中的回调函数

需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,

主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,

所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。

javascript写手如果称一个函数为"异步的",其意思是这个函数会导致将来再运行另一个函数

后者取自于事件队列(若后面这个函数是作为参数传递给前者的,则成为前者的回调函数)

理解了异步任务的任务队列后:

demo1:

var ajaxRequest=new XMLHttpRequest();

ajaxRequest.open("GET","data/activity.json",true)

ajaxRequest.send(null)      

while(ajaxRequest.readyState ===1){ //当有发出open请求 readyState为1

alert(1) //无限弹1,当然永远也轮不懂send运行

}

//ajaxRequest.readyState ===4也是不行的 因为当readyState===4时,while已经执行完了

//所以需要引入事件监听(例如onreadystatechange)把异步的任务返回主线程的任务队列

//ajaxRequest.send(null) //异步任务在同步任务全部完成后执行   即send真正的执行位置

readyState,onreadystatechange都是要依赖异步的send函数发回来的状态,不过时间微秒级

onreadystatechange对应的函数相当于send的回调函数,要在send执行后才能执行

(这就是事件监听的用处:返回任务队列)

demo2:

var a=10;

var ajaxRequest=new XMLHttpRequest();

ajaxRequest.open("GET","data/activity.json",true)

ajaxRequest.send(null)

ajaxRequest.onreadystatechange=function(){  //异步事件队列返同步任务对的事件监听

console.log("我是ajax请求回来触发事件监听的标志")

console.log("异步任务ajax请求回来触发事件监听的时刻",new Date().getTime()-c)

}

setTimeout(function(){

console.log("同步任务执行完0.004秒后立刻执行,setTimeout函数实际的延时时间会有偏差")

console.log("异步任务setTimeout执行的时刻",new Date().getTime()-c)

a++

console.log("异步队列返回同步队列,a="+a);

},0)

console.log("同步任务","a="+a)

var four = new Date();

var c = four.getTime()

for(var i=0;i<1000000000;i++){

if(i === 0){

console.log("同步任务,i=0时执行的时刻:",new Date().getTime()-c)

}

if(i === (1000000000-1)){

console.log("同步任务,i=999999时执行的时刻:",new Date().getTime()-c)

console.log("ajax的send()是在我执行完它才开始请求的,并不是我在进行的同时它也在请求,所以send()函数放在脚本的结尾和现在是一样的效果")

}

}

//ajaxRequest.send(null)           //实际上异步的send函数是在主线程空了再执行  也就是脚本的结尾

相关文章

  • JavaScript异步编程好文摘要

    JavaScript之异步编程简述JavaScript异步编程

  • ajax

    ajax async javascript and xml在ajax的异步不是我们理解的同步异步编程,而是泛指局部...

  • part1整理

    函数式编程:JavaScript函数式编程指南 异步编程:异步编程 Promise源码 JavaScript基础知...

  • ES6文章合集

    一、深入理解ES6异步编程 JavaScript 的单线程,如果没有异步编程的话将会苦不堪言。ES6 之前,异步编...

  • Javascript的异步编程的理解

    在单线程的javascript编程来说,所有的任务分为两种,一种是同步任务(synchronous), 另一种是异...

  • 一篇看完JS异步编程的进阶史

    一、Javascript实现异步编程的过程以及原理 1、为什么要用Javascript异步编程 众所周知,Java...

  • ES6 之 Promise

    Promise是JavaScript异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步...

  • JavaScript(ES6) - Async

    异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...

  • Javascript------异步编程的4种方法

    Javascript异步编程的4种方法

  • 深入了解下Promise

    Promise 意义 Promise 的诞生与 Javascript 中异步编程息息相关,js 中异步编程主要指 ...

网友评论

      本文标题:Javascript的异步编程的理解

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