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就像一条流水线,仅仅是一条流 ...
随机推荐
- 非web环境的注解配置的spring项目应用(non-web, Spring-data-jpa, JavaConfig, Java Application, Maven, AnnotationConfigApplicationContext)
非web环境的spring应用 springframework提供的spring容器,非常适合应用于javaweb环境中. 同时,spring组件的低耦合性为普通java应用也提供了足够的支持. 以下 ...
- systemctl启动tomcat后,jps看不到进程
centos7 写了tomcat的启动脚本,脚本从网上copy的. [Unit]Description=tomcat-1After=syslog.target network.target remot ...
- java学习-- String
String 类的实例是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了 String 类是不可改变的解析,例如: String s = "Google"; ...
- web中ios移动端软键盘收起后,页面内容留白不下滑
微信里面打开web页面,在ios软键盘收起时,页面键盘位置的内容留白,如下图 这个问题纠结了很久,然后请教了老大(威哥),看到页面老大给出的方案就是代码改变滚动条的位置. 这里就监听键盘收起的事件,来 ...
- 1503.02531-Distilling the Knowledge in a Neural Network.md
原来交叉熵还有一个tempature,这个tempature有如下的定义: \[ q_i=\frac{e^{z_i/T}}{\sum_j{e^{z_j/T}}} \] 其中T就是tempature,一 ...
- jQuery中删除方法empty(),remove()和detach()的区别
empty():清空匹配的元素集合中所有的子节点,自身节点和事件都未被删除. remove():这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来再使用这些匹配的元素.但除了这个元素本身 ...
- IOS 微信返回按钮事件控制弹层关闭还是返回上一页
在微信公共号内绑定域名后或微信内打开第三方链接跳转非单页面网站时,经常会有弹层Modal的需求,此时如果用户习惯性点击微信自带的返回“<”按钮,就会跳转回上一页或退出网站,而为了避免这种不好的误 ...
- 20175213 2018-2019-2 《Java程序设计》第8周学习总结
教材学习内容总结 1:泛型主要目的是建立具有类型安全的集合框架,如链表,散列映射等数据结构. 泛型类的声明: class People<E> People是泛型类的名称,E是其中泛型,E可 ...
- Nancy.Net之旅-初次见面
Welcome Nancy 首先,欢迎来到Nancy!我们的主要灵感是Ruby的Sinatra框架,因此Nancy以Frank Sinatra的女儿名字命名.许多人想知道NancyFx中的Fx是什 ...
- pyautogui 文档(四):消息框功能
消息框功能 PyAutoGUI利用PyMsgBox中的消息框函数提供跨平台的纯Python方式来显示JavaScript样式的消息框.提供了四个消息框功能: alert()函数 >>> ...