你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。
那么这里说的同步和异步到底是什么呢?如果你真的不懂,我希望你认真读完这篇文章。其实我个人觉得js官方的文档在使用两个词的时候并不准确,包括很多其他词汇,都只是听起来高深,但实际应用好像跟这些词没半毛钱关系。例如“事件委托”这个词,不知道的人乍一看谁又能说出“事件委托”是什么意思?委托什么事件?怎么个委托,我看不如干脆就叫“事件在外层元素中的捕获”,虽然长一点,一下就能看懂。
回归正轨,“同步”——一下就让人想到“一起”这个词;“异步”呢,从字面来讲,好像是在不同的(异)的ways上do something,那首先想到的词可能是“一边...一边...”,比如‘小明一边吃雪糕一边写作业’,这完全没毛病,雪糕吃完了,作业也写完了,这就是异步?那就大错特错了!
其实同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
最基础的异步是setTimeout和setInterval函数,很常见,但是很少人有人知道其实这就是异步,因为它们可以控制js的执行顺序。我们也可以简单地理解为:可以改变程序正常执行顺序的操作就可以看成是异步操作。如下代码:

 1 <script type="text/javascript">
 2 console.log( "1" );
 3  setTimeout(function() {
 4  console.log( "2" )
 5  }, 0 );
 6  setTimeout(function() {
 7 console.log( "3" )
 8 }, 0 );
 9  setTimeout(function() {
10 console.log( "4" )
11 }, 0 );
12 console.log( "5" );
13 </script>

输出顺序是什么呢?

可见,尽管我们设置了setTimeout(function,time)中的等待时间为0,结果其中的function还是后执行。
火狐浏览器的api文档有这样一句话:Because even though setTimeout was
 called with a delay of zero, it's placed on a queue and scheduled to run at the next opportunity, not immediately. Currently executing code must complete before functions on the queue are executed, the resulting execution order may not be as expected.
意思就是:尽管setTimeout的time延迟时间为0,其中的function也会被放入一个队列中,等待下一个机会执行,当前的代码(指不需要加入队列中的程序)必须在该队列的程序完成之前完成,因此结果可能不与预期结果相同。
这里说到了一个“队列”(即任务队列),该队列放的是什么呢,放的就是setTimeout中的function,这些function依次加入该队列,即该队列中所有function中的程序将会在该队列以外的所有代码执行完毕之后再以此执行,这是为什么呢?因为在执行程序的时候,浏览器会默认setTimeout以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,在所有不耗时程序执行过后,再来依次执行该队列中的程序。
又回到了最初的起点——javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。于是JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。
具体来说,异步运行机制如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。 
"任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等),比如$(selectot).click(function),这些都是相对耗时的操作。只要指定过这些事件的回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码,前面说的点击事件$(selectot).click(function)中的function就是一个回调函数。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。例如ajax的success,complete,error也都指定了各自的回调函数,这些函数就会加入“任务队列”中,等待执行。

原文链接:https://blog.csdn.net/qq_22855325/article/details/72958345

转载于:https://www.cnblogs.com/zr123/p/9257543.html

js中对同步和异步的理解相关推荐

  1. js中的同步和异步的个人理解

    你应该知道,javascript语言是一门"单线程"的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条 ...

  2. 如何理解js中的同步和异步

    首先需要理解:JS是单线程运行的 同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同. 同步就是程序按照正常的执行顺序,依次执行 ...

  3. JS笔记(20): JS中的同步编程和异步编程

    铺垫:关于定时器 定时器:设定一个定时器,并且设定了等到的时间,当到达指定的时间,浏览器会把对应的方法执行 1)常用的定时器 1.setTimeout(function,intarval) 执行一次 ...

  4. [js] 说说你对JS中暂性死区的理解,它有什么运用场景?

    [js] 说说你对JS中暂性死区的理解,它有什么运用场景? var v=1; {v = 2;let v; }这里候会报错: Cannot access 'v' before initializatio ...

  5. 线程中的同步和异步的区别

    线程中的同步和异步的区别 一.同步        所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作.是多个线程同时访问同一资源,等待资源访问结束,浪费时间,效率不 ...

  6. JS中同步与异步的理解

    你应该知道,javascript语言是一门"单线程"的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条 ...

  7. 理解js中的同步和异步

    首先要先了解下js单线程 一.为什么js是单线程? 其实,JavaScript的单线程,与它的用途是有很大关系,我们都知道,JavaScript作为浏览器的脚本语言,主要用来实现与用户的交互,利用Ja ...

  8. js中对于数据类型的一些理解

    Typeof的作用: 返回数据的类型 基本数据类型(Number String Boolean null undefined  es6种新增的一个基本数据symbol) Let num = 22 Ty ...

  9. java js中 function函数报错_浅析JS中对函数function的理解(基础篇)

    正文:我们知道,在js中,函数实际上是一个对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法.因此,函数名实际上是指向函数对象的指针,不与某个函数绑定.在常见的两种定 ...

  10. XCP协议中关于同步数据传输的理解和应用

    根据数据传输的方向不同,XCP协议中,同步数据传输可以分为如下两种类型: DAQ: ECU(slave)向上位机(master)发送数据,实现数据采集 STIM: 上位机(master)向ECU(sl ...

最新文章

  1. 【MATLAB】单元数组类型
  2. 深度学习100例-卷积神经网络(CNN)识别眼睛状态 | 第17天
  3. 4kyu Path Finder #2: shortest path
  4. shopex还是ecshop
  5. Python实现kNN算法
  6. 汇编基础知识之输入输出
  7. 让程序在崩溃时体面的退出之SEH
  8. Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
  9. 数学特级老师:数学除了做习题,这份140G的资料一定要收藏!
  10. python中if控制语句_了解Python控制流语句——if语句
  11. 从零开始造一个“智障”聊天机器人
  12. 双缓冲(Double Buffer)原理和使用【转】
  13. 理解高性能Python
  14. 【CV】用于计算机视觉的 Transformer 高被引综述
  15. Web前端期末大作业-食品零售综合商城模板网页设计源码(HTML+CSS)
  16. jvm 字节码jclasslib解读
  17. Python制作一个简单的图片文字提取+PDF转WORD的软件
  18. C#简单实现摄影测量后方交会
  19. Sqlserver 中的Iif语句
  20. c#截屏木马,发送到邮箱

热门文章

  1. MPLS virtual private network中MCE介绍
  2. ETH-TRUNK链路原理和实验
  3. 网络层QoS分类和标记字段详解
  4. [解题报告]12289 - One-Two-Three
  5. 【对讲机的那点事】安装中继台天馈系统如何制作同轴电缆BNC接头?
  6. 【js高三】---js模块模式
  7. RSA加解密VS加签与验签
  8. 如果这样 你跟小三走吧
  9. java 内存快照怎么看_jvm工具篇-(1)-分析工具MAT使用(内存快照分析)
  10. C#对MySql进行增删该查