js的异步执行
1.Javascript语言的执行环境是”单线程”(single thread):
优点:实现起来比较简单,执行环境相对单纯;
缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
2.”异步模式”编程的几种方法:
(1)回调函数:优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),使得程序结构混乱、流程难以追踪(尤其是回调函数嵌套的情况),而且每个任务只能指定一个回调函数。
(2)采用事件驱动模式(事件监听):优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以”去耦合“(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。
(3)观察者模式(发布\订阅模式):这种方法的性质与”事件监听”类似,但是明显优于后者。因为我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
3.异步操作的流程控制。
(1)串行执行:编写一个流程控制函数,让它来控制异步任务,一个任务完成以后,再执行另一个。
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];
function series(item) {
if(item) {
async( item, function(result) {
results.push(result);
return series(items.shift());
});
} else {
return final(results);
}
}
series(items.shift());
函数series就是串行函数,它会依次执行异步任务,所有任务都完成后,才会执行final函数。items数组保存每一个异步任务的参数,results数组保存每一个异步任务的运行结果。
(2)并行执行:所有异步任务同时执行,等到全部完成以后,才执行final函数。
//forEach方法会同时发起6个异步任务,等到它们全部完成以后,才会执行final函数。
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = []; items.forEach(function(item) {
async(item, function(result){
results.push(result);
if(results.length == items.length) {
final(results);
}
})
});
并行执行的好处是效率较高,比起串行执行一次只能执行一个任务,较为节约时间。但是问题在于如果并行的任务较多,很容易耗尽系统资源,拖慢运行速度。因此有了第三种流程控制方式。
(3)并行与串行的结合:设置一个门槛,每次最多只能并行执行n个异步任务。这样就避免了过分占用系统资源。
//变量running记录当前正在运行的任务数,只要低于门槛值,就再启动一个新的任务
//如果等于0,就表示所有任务都执行完了,这时就执行final函数
//最多只能同时运行两个异步任务。
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];
var running = 0;
var limit = 2; function launcher() {
while(running < limit && items.length > 0) {
var item = items.shift();
async(item, function(result) {
results.push(result);
running--;
if(items.length > 0) {
launcher();
} else if(running == 0) {
final();
}
});
running++;
}
} launcher();
如有错误,请您指正!
参考文档:
js的异步执行的更多相关文章
- 如何使js函数异步执行
CallbacksCallbacks使用场景在哪里?在很多时候需要控制一系列的函数顺序执行.那么一般就需要一个队列函数来处理这个问题: function Aaron(List, callback) { ...
- js 后台异步执行
public void AlertMsg(string msg, bool async) { string script = string.Format("alert('{0}'); &qu ...
- 浅析JS异步执行机制
前言 JS异步执行机制具有非常重要的地位,尤其体现在回调函数和事件等方面.本文将针对JS异步执行机制进行一个简单的分析. 从一份代码讲起 下面是两个经典的JS定时执行函数,这两个函数的区别相信对JS有 ...
- 异步执行js脚本——防止阻塞
JS允许我们修改页面中的所有方面:内容,样式和用户进行交互时的行为. 但是js同样可以阻塞DOM树的形成并且延迟页面的渲染. 让你的js变成异步执行,并且减少不必要的js文件从而提高性能. JavaS ...
- 获取node异步执行结果的方式
拿数据库操作举例: var connection = mysql.createConnection(); connection.query(sql,function(err,rows){xxx} ); ...
- (转载)js引擎的执行过程(二)
概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 语法分析: 分别对加载完成的代码块进行语法检验,语法正 ...
- js文件引用方式及其同步执行与异步执行
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp74 任何以appendChild(scriptNode) 的方式引入 ...
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- 不阻塞浏览器的解析,待外部js下载完成后异步执行
网站统计中的数据收集原理及实现(js埋点实现) - lastwhisper - CSDN博客 https://blog.csdn.net/l1212xiao/article/details/80450 ...
随机推荐
- Virtualbox 虚拟机支持硬件摄像头
最近我们公司做了一个摄像头项目,需要测试各种浏览器的情况,我就安装了一个Win xp的虚拟机,但是发现无法找到摄像头,经过查阅资料找到了解决办法 前提环境 Mac电脑 Virtualbox 虚拟机 虚 ...
- Resharper 8.2 注册码
用户名:ronle注册码:ZoJzmeVBoAv9Sskw76emgksMMFiLn4NM
- 基于 Token 的身份验证方法
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Toke ...
- android 中获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)
final int[] location = new int[2]; view.getLocationOnScreen(location); final int[] location = new in ...
- 移动Web开发调研
背景 在移动互联网浪潮下,移动设备普及,对配置需要考虑移动端设备可访问性.Web作为最贴近用户的配置手段,面向从PC端传统页面,向移动端页面的转型. 概念 PC Web: 面向传统PC电脑的浏览器开发 ...
- SD卡读写一些函数
/SPI2 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 SPI2_ReadWriteByte(u8 TxData) { u16 retry=0; while((S ...
- HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)
http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...
- sprint 3 总结
1.要求: 演示可参考毕业设计答辩,包含两部分内容: 项目陈述,可综述项目.团队.开发过程等. 运行演示,实现的功能.业务.用户反馈等. 希望各组认真准备,拿出最好的阵容最好的状态,展示一学期的学习与 ...
- JS调用OC方法并传值,OC调用JS方法并传值////////////////////////zz
iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码) 最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点 ...
- gradle使用
查看子工程引用的jar包 gradle child_project:dependencies > dep.txt