js异步与同步的区别

article/2025/11/11 10:20:56

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

那么这里说的同步和异步到底是什么呢?如果你真的不懂,我希望你认真读完这篇文章。其实我个人觉得js官方的文档在使用两个词的时候并不准确,包括很多其他词汇,都只是听起来高深,但实际应用好像跟这些词没半毛钱关系。例如“事件委托”这个词,不知道的人乍一看谁又能说出“事件委托”是什么意思?委托什么事件?怎么个委托,我看不如干脆就叫“事件在外层元素中的捕获”,虽然长一点,一下就能看懂。

回归正轨,“同步”——一下就让人想到“一起”这个词;“异步”呢,从字面来讲,好像是在不同的(异)的ways上do something,那首先想到的词可能是“一边...一边...”,比如‘小明一边吃雪糕一边写作业’,这完全没毛病,雪糕吃完了,作业也写完了,这就是异步?那就大错特错了!

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

最基础的异步是setTimeout和setInterval函数,很常见,但是很少人有人知道其实这就是异步,因为它们可以控制js的执行顺序。我们也可以简单地理解为:可以改变程序正常执行顺序的操作就可以看成是异步操作。如下代码:

<script type="text/javascript">console.log( "1" );setTimeout(function() {console.log( "2" )}, 0 );setTimeout(function() {console.log( "3" )}, 0 );setTimeout(function() {console.log( "4" )}, 0 );console.log( "5" );
</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也都指定了各自的回调函数,这些函数就会加入“任务队列”中,等待执行。

本文思想来源:http://www.cnblogs.com/c3gen/p/6170504.html  

如何实现异步编程请看阮一峰老师的:  http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html

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

   // 1. 同步

    // 2. process.nextTick

    // 3. 微任务

    // 4. 宏任务( 计时器, ajax, 读取文件)

    // 5.setImmediate


http://chatgpt.dhexx.cn/article/sULcxDO4.shtml

相关文章

同步调制和异步调制区别

在PWM控制电路中&#xff0c;载波频率 fc 和调制信号频率 fr 之比成为载波比&#xff0c;根据载波信号和信号波信号是否同步分为同步调制和异步调制。 1 什么是异步调制&#xff1f; 载波信号和调制信号不保持同步的方式称为异步调制&#xff0c;如下图所示&#xff0c;异步调…

同步和异步,区别

同步&#xff1a; 同步的思想是&#xff1a;所有的操作都做完&#xff0c;才返回给用户。这样用户在线等待的时间太长&#xff0c;给用户一种卡死了的感觉&#xff08;就是系统迁移中&#xff0c;点击了迁移&#xff0c;界面就不动了&#xff0c;但是程序还在执行&#xff0c;…

java同步和异步的区别_java中同步与异步区别是什么

一、同步与异步概念&#xff1a;(推荐&#xff1a;java视频教程) 1.同步&#xff1a;所有的操作都做完&#xff0c;才返回给用户。这样用户在线等待的时间太长&#xff0c;给用户一种卡死了的感觉(就是系统迁移中&#xff0c;点击了迁移&#xff0c;界面就不动了&#xff0c;但…

ajax什么是异步和同步,ajax异步和同步的区别

AJAX异步 打个比方吧,通常情况下,用户注册,那么用户首先得填写好表单,然后点提交,这样表单就会向服务发出一个请求,则服务器处理代码,如果用户存在,则返回一个信息。总之,就是所有的数据需要你点提交后,信息才会发送! 而AJAX就相当于是模拟了一个信息发送请求,你可…

java8拉姆达表达式对Object去重复

java8拉姆达表达式对Object去重复 public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {Map<Object, Boolean> seen new ConcurrentHashMap<>();return object -> seen.putIfAbsent(keyExtractor.a…

拉姆达表达式 filter与map的讲解

filter 根据条件过滤元素 map 获取(映射)每个元素,并对其进行操作 参考链接

sort()与拉姆达表达式

sort()与拉姆达表达式的结合 #include <iostream> #include <string> #include <vector> #include <ctime> #include <map> #include <utility> #include <algorithm>using std::cout; using std::endl; using std::string; using …

java 拉姆达表达式_一看就懂之java8新特性函数式编程:我是拉姆达表达式lambda...

我们都知道&#xff0c; java8之后增加了很多新特性&#xff0c;大大的简化了代码的编写、阅读的负担。 先发个牢骚&#xff1a; 今天up主根据自己的理解跟大家说说新特性之一的lambda express(拉姆达表达式)&#xff0c;每当看到新的语法改动&#xff0c;内心我都是拒绝的。因…

拉姆达表达式学习(1)

我曾经遇到一个项目,项目里面需要经常对一系列的同类型集合进行操作,如对集合进行增加元素,删除集合的指定索引的元素等等.    我们可以使用ArrayList来进行.如 1 ArrayList stringListnew ArrayList(); 2 stringList.Add("大家好"); 3 stringList.Add("你们好…

拉姆达表达式记录 + log日志+代码

目录 71. item.label $"{lstD[i].DeptName}({lstCamera.Count})";72. 定义entity时不写传统的{get&#xff1b;set&#xff1b;}73.74. EF多对多75. DateTime.Now.Subtract(x.GpsTime).TotalHours76. queryModel.LogDate.Value.Year77. .net导出Excel78. User.Ident…

List.sort()方法使用拉姆达表达式进行排序的一个例子

这是牛客网华为java题库的一道题&#xff1a;HJ26 字符串排序 题中要求&#xff0c;对字符串中的英文字母不分大小写按照字典顺序排序&#xff0c;遇到相同的字母&#xff0c;要求保持它们的相对顺序不变&#xff0c;非英文字母字符保持原位置不变。例如&#xff1a; 输入&…

拉姆达表达式

1、Queryable 用于拉姆达表达式操作 //---------Queryable<T>,扩展函数查询---------// //---------Queryable<T>,扩展函数查询---------////针对单表或者视图查询//查询所有 var student db.Queryable<Student>().ToList(); var studentDynamic db.Querya…

java 拉姆达表达式_Java8中foreach与拉姆达表达式的组合使用

1. forEach and Map 1.1 通常这样遍历一个Map Map items = new HashMap<>(); items.put("A", 10); items.put("B", 20); items.put("C", 30); items.put("D", 40); items.put("E", 50); items.put("F", 60)…

Matlab系列之数组(矩阵)的生成

从本篇开始&#xff0c;会有一段时间都将用于记录数组、矩阵的操作等等&#xff0c;如果以前没有接触过相关的&#xff0c;可能会觉得要展示的是很复杂的东西&#xff0c;但并不是&#xff0c;这是一个很简单的部分&#xff0c;但也是一个很重要的部分&#xff0c;至少现在的我…

MATLAB-数组的使用

数组的使用&#xff08;持续更新&#xff09; randperm--数组随机排列permute--置换数组维度cat--串联数组squeeze--删除数组中长度为1的维度reshape--重构数组repmat--重复数组副本数组中的&#xff1a;sort-数组的排序dig-创建对角矩阵eig--特征值和特征向量magic--幻方矩阵m…

matlab定义数组和相关函数

matlab作为一个大型的计算软件&#xff0c;里面有许多对数组的操作&#xff0c;所以数组的定义和数组的操作是一个必不可少的部分。 1 数组的定义 在matlab中对数组的定义较为灵活&#xff0c;因为特殊矩阵较多&#xff0c;所以有许多特定的定义方法。比较常见的有三种&#…

Matlab的数组索引

在 MATLAB中&#xff0c;根据元素在数组中的位置&#xff08;索引&#xff09;访问数组元素的方法主要有三种&#xff1a;按位置索引、线性索引和逻辑索引。 按元素位置进行索引 最常见的方法是显式指定元素的索引。例如&#xff0c;要访问矩阵中的某个元素&#xff0c;请依序…

Matlab笔记-数组

一、结构数组的基本使用 结构体的定义即为C语言中结构体的初始化&#xff0c;其引用成员&#xff08;在Matlab中为field,字段的意思&#xff09;和C语言相同。 1、直接赋值 >> student(1).nameSilen; student(1).id1234; student(1).grade[1 2 3;4 5 6;7 8 9]; stude…

matlab三维数组

三维数组的定义&#xff1a;在MATLAB中&#xff0c;习惯性的将二维数组的第一维称为“行”&#xff0c;第二维称为“列”&#xff0c;而于三维数组&#xff0c;其第三维习惯性地称为“页”。 定义一个三维数组&#xff1a; A&#xff08;2&#xff0c;2&#xff0c;2&#xf…

MATLAB基础——关于数组(一)

变量和数组 MATLAB程序的基本数据单元是数组&#xff0c;标量在MATLAB中也被当做数组来处理 数组可以定义为向量&#xff08;一般描述为一维数组&#xff09;或矩阵&#xff08;一般描述为二维或多维&#xff09; 访问数组中的元素&#xff1a;数组名&#xff08;&#xff09;…