JS基础——同步异步的区别

javascript语言是一门“单线程”的语言,
不像java语言,类继承Thread再来个thread.start就能够开辟一个线程。
因此,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。javascript

“同步”——一下就让人想到“一块儿”这个词;java


“异步”呢,从字面来说,好像是在不一样的(异)的ways上do something,
那首先想到的词多是“一边...一边...”,好比‘小明一边吃雪糕一边写做业’,这彻底没毛病,雪糕吃完了,做业也写完了,这就是异步?那就大错特错了!ajax


其实同步和异步,
不管如何,作事情的时候都是只有一条流水线(单线程)
同步和异步的差异就在于这条流水线上各个流程的执行顺序不一样。浏览器

最基础的异步是setTimeout和setInterval函数,
很常见,可是不多人有人知道其实这就是异步,
由于它们能够控制js的执行顺序。咱们也能够简单地理解为:
能够改变程序正常执行顺序的操做就能够当作是异步操做。以下代码:网络

console.log( "1" );
    setTimeout(function() {
        console.log( "2" )
    }, 0 );
    setTimeout(function() {
        console.log( "3" )
    }, 0 );
    setTimeout(function() {
        console.log( "4" )
    }, 0 );
    console.log( "5" );

输出顺序是什么呢?异步

clipboard.png

可见,尽管咱们设置了setTimeout(function,time)中的等待时间为0,结果其中的function仍是后执行。async

尽管setTimeout的time延迟时间为0,
其中的function也会被放入一个队列中,等待下一个机会执行,
当前的代码(指不须要加入队列中的程序)必须在该队列的程序完成以前完成,
所以结果可能不与预期结果相同。函数

这里说到了一个“队列”(即任务队列),
该队列放的是什么呢,放的就是setTimeout中的function,
这些function依次加入该队列,
即该队列中全部function中的程序将会在该队列之外的全部代码执行完毕以后再以此执行,
这是为何呢?由于在执行程序的时候,浏览器会默认setTimeout以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),
将其加入一个队列中,该队列是一个存储耗时程序的队列,在全部不耗时程序执行事后,再来依次执行该队列中的程序。spa

又回到了最初的起点——javascript是单线程。 单线程就意味着,全部任务须要排队,前一个任务结束,才会执行后一个任务。
若是前一个任务耗时很长,后一个任务就不得不一直等着。

因而就有一个概念——任务队列。若是排队是由于计算量大,CPU忙不过来,倒也算了,
可是不少时候CPU是闲着的,由于IO设备(输入输出设备)很慢(好比Ajax操做从网络读取数据),不
得不等着结果出来,再往下执行。因而JavaScript语言的设计者意识到,这时主线程彻底能够无论IO设备,
挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回告终果,再回过头,把挂起的任务继续执行下去。.net

因而,全部任务能够分红两种,

一种是同步任务(synchronous),另外一种是异步任务(asynchronous)。 同步任务指的是,在主线程上排队执行的任务,
只有前一个任务执行完毕,才能执行后一个任务; 异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,
只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。

具体来讲,异步运行机制以下:


  1. 全部同步任务都在主线程上执行,造成一个执行栈(execution context stack)。
  2. 主线程以外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
  3. 一旦"执行栈"中的全部同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,因而结束等待状态,进入执行栈,开始执行。
  4. 主线程不断重复上面的第三步。

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

"任务队列"中的事件,除了IO设备的事件之外,
还包括一些用户产生的事件(好比鼠标点击、页面滚动等等),
好比$(selectot).click(function),这些都是相对耗时的操做。
只要指定过这些事件的回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。

所谓"回调函数"(callback),就是那些会被主线程挂起来的代码,前面说的点击事件$(selectot).click(function)中的function就是一个回调函数。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。例如ajax的success,complete,error也都指定了各自的回调函数,这些函数就会加入“任务队列”中,等待执行。

做者:YinghaoGuo
来源:CSDN
原文:https://blog.csdn.net/qq_2285... 版权声明:本文为博主原创文章,转载请附上博文连接!

相关文章
相关标签/搜索