JS中的同步和异步
javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。
所以同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
1、最基础的异步是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以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,
在所有不耗时程序执行过后,再来依次执行该队列中的程序。
2、又回到了最初的起点——javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不
得不一直等着。于是就有一个概念——任务队列。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很
慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。于是JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任
务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务
执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,
请求执行任务,该任务才会进入主线程执行。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等),比如$(selectot).click(function),这些都是相对耗时的操作。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码,前面说的点击事件$(selectot).click(function)中的function就是一个回调函数。异步任务必须指定回调函
Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调 Promise对象代表一个未完成、但预计将来会完成的操作。
它有以下三种状态:
pending:初始值,不是fulfilled,也不是rejectedfulfilled:代表操作成功rejected:代表操作失败
/* 例3.1 */
//构建Promise
var promise = new Promise(function (resolve, reject) {
if (/* 异步操作成功 */) {
resolve(data);
} else {
/* 异步操作失败 */
reject(error);
}
});
类似构建对象,我们使用new来构建一个Promise。Promise接受一个「函数」作为参数,该函数的两个参数分别是resolve和reject。这两个函数就是就是「回调函数」,由JavaScript引擎提供。
resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去; reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数。
/* 接例3.1 */
promise.then(onFulfilled, onRejected); promise.then(function(data) {
// do something when success
}, function(error) {
// do something when failure
});
then方法会返回一个Promise。它有两个参数,分别为Promise从pending变为fulfilled和rejected时的回调函数(第二个参数非必选)。这两个函数都接受Promise对象传出的值作为参数。
简单来说,then就是定义resolve和reject函数的,其resolve参数相当于:
function resolveFun(data) {
//data为promise传出的值
}
而新建Promise中的'resolve(data)',则相当于执行resolveFun函数。
Promise新建后就会立即执行。而then方法中指定的回调函数,将在当前脚本所有同步任务执行完才会执行。
JS中的同步和异步的更多相关文章
- 关于js中的同步和异步
最近看到前端面试问到js中的同步和异步,这个问题该怎么回答? 梳理一下,js对于异步的处理,很多人的第一反应是ajax,这只能说是对了一半. 1.个人觉得,js中,最基础的异步是setTimeout和 ...
- node.js中对同步,异步,阻塞与非阻塞的理解
我们都知道javascript是单线程的,node.js是一个基于Chrome V8 引擎的 javascript 运行时环境,注意 node.js 不是一门语言,别搞错了. javascript为什 ...
- js中的同步与异步
同步:提交后等待服务器的响应,接收服务器返回的数据后再执行下面的代码 异步:与上面相反,提交后继续执行下面的代码,而在后台继续监听,服务器响应后有程序做相应处理,异步的操作好处是不必等待服务器而 ...
- Promise-js中的同步和异步
js中的同步和异步 自从读了研后,走上了学术之路,每天除了看论文就是做实验,最后发现自己还是喜欢开发呀,于是我又重回前端啦~ 隔了这么久没学前端,好像很多东西都忘了不少,而且不得不说前端的技术更新 ...
- JS中的同步异步问题
<script> /* * JS 是单线程 * 同步 异步 * 常见的异步 * 1.定时器 * 2.事件绑定 * 3.ajax请求(一般的都是异步) * 4.回调函数也可以理解成 异步 * ...
- JS中的同步异步编程
首先我们先看看同步与异步的定义,及浏览器的执行机制,方便我们更好地理解同步异步编程. 浏览器是多线程的,JS是单线程的(浏览器只分配一个线程来执行JS) 进程大线程小:一个进程中包含多个线程,例如 ...
- 【Mocha.js 101】同步、异步与 Promise
前情提要 在上一篇文章<[Mocha.js 101]Mocha 入门指南>中,我们提到了如何用 Mocha.js 进行前端自动化测试,并做了几个简单的例子来体验 Mocha.js 给我们带 ...
- 让你高效的理解JavaScript中的同步、异步和事件循环
"同步请求","异步请求"相信这两词在程序猿的世界中频频出现,到底是词性的妖娆,还是撸代码的基础要求,下面直接分享本人学习的好东西,保证让你深入浅出,爽得不要不 ...
- js中对同步和异步的理解
你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流 ...
随机推荐
- QT项目添加现有文件后不能运行,MFC在类视图中自动隐藏类
解决方案:1)QT 5.6版本的QtCreator打开pro文件,在最后加一行空行或者删除一行空行,保存即可: 2)在隐藏的类对应的头文件中增加一行或删除一行(空格也可以),即可自动出现.
- VB6 二维数组去重实现
关于VB6的二维数组去重算法实现 当然,这里还是有局限性,当我们的数组被填满了各个不同的值时,例如下方 700*700 = 490000 就要While49万次,这谁受得了? 所以以下仅适合小规模使用 ...
- generator 生成器
L=[i*i for i in range(10)] print(L) G=(i*i for i in range(10)) #变中括号为小括号 print(G) 另一种方法: fib(max): n ...
- windows+Pycharm+Anaconda下安装opencv
本人最近开始使用pycharm,之前一直是在Anaconda环境下跑的程序,在Anaconda Navigator下运行,但发现Jupyter Notebook界面下的程序提示不是很人性化,所以迁移到 ...
- MySQL InnoDB 事务实现过程相关内容的概述
MySQL事务的实现涉及到redo和undo以及purge,redo是保证事务的原子性和持久性:undo是保证事务的一致性(一致性读和多版本并发控制):purge清理undo表空间背景知识,对于Inn ...
- Your branch and remoteBranchName have diverged solution
(zhuan)git pull时解决分支分叉(branch diverged)问题 git pull时出现分支冲突(branch diverged) $ git status # On branch ...
- 将对象序列化成XML字符串
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- 为sqlserver数据库添加专用用户名
在安全里面右键添加登录名,输入登录名与密码(可以取消强制密码策略)然后选择用户映射的数据库,勾选db_owner即可.
- MongoDB - 1
MongoDB - 1 一.初识MongoDB 之 什么东西都得先从理论入手,你说是不是啊? MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展 ...
- phpstorm界面不停的indexing,不停的闪烁
选择 File->Invalidate Caches / Restart...->Invalidate and Restart,就行了!