需知:

1,JavaScript只有一个核心的主线程,但它有存放异步任务的任务队列(task queue)。
2,主线程中是正在运行的同步任务(异步任务开始运行则也会变为同步任务),每次同步任务完成后就会去查看异步任务列表,如果查看时有异步任务达到它的运行条件(比如AJAX请求返回了结果)则把此任务放入主线程中开始执行,主线程的同步任务完成了又会去查看异步任务列表中的每个任务是否达到运行条件,如此往复,直到主线程中的同步任务全部完成以及异步任务列表清空了则脚本结束。
3,回调函数是异步操作最基本的方法,有回调函数的函数将成为异步任务被挂起,(在JavaScript中,回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。)
4,事件监听也是异步任务。
5,“发布/订阅模式”(又称为:“观察者模式”(observer pattern)),事件完全可以理解成“信号”,如果存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”(publish)一个信号,其他任务可以向信号中心“订阅”(subscribe)这个信号,从而知道什么时候自己可以开始执行。

异步操作的流程控制

1,流程控制之串行执行

// 1,流程控制之串行执行(串行执行是最常见的任务执行流程,比较直观,运行效率稍低于串并行执行,再就是并行执行,但是占用的系统资源是最少的)
var items = [1, 2, 3, 4, 5, 6]; //每个任务的参数
var results = []; //每个任务的结果function async (arg, callback) { //带有回调函数的函数被视作异步任务,// 没有达到此异步任务的执行条件将会被引擎放入任务列表被挂起,达到异步任务执行条件执行时会通过回调函数进入主线程,// 主线程中执行的都是同步任务,异步任务开始执行后也变成的同步任务。console.log('参数为 ' + arg + ' , 1秒后返回结果');setTimeout(function () {callback(arg * 2);}, 1000);
}function final(value) { //任务列表执行完成后最终调用的函数console.log('完成: ', value);
}// 流程控制函数之串行执行(serial:串行)
function series(item) {if (item) { //如果参数不为null或undefined,则执行此次异步任务async (item, function (result) {results.push(result); //把每次运行结果放入results数组中return series(items.shift()); //递归series函数以进行下次任务});} else { //items中的参数全部用完则任务全部完成,跳出递归,运行final()return final(results[results.length - 1]);}
}series(items.shift()); //开始启动任务列表

2,流程控制之并行执行

// 2,流程控制之并行执行,(并行执行的效率较高,比起串行执行一次只能执行一个任务,较为节约时间。但是问题在于如果并行的任务较多,很容易耗尽系统资源,拖慢运行速度。)
var items = [1, 2, 3, 4, 5, 6];
var results = [];function async (arg, callback) { //任务console.log('参数为 ' + arg + ' , 1秒后返回结果');setTimeout(function () {callback(arg * 2);}, 1000);
}function final(value) { //任务列表完成后执行的函数console.log('完成: ', value);
}items.forEach(function (item) { //遍历参数列表,一个参数代表一个任务,回调函数创建异步任务async (item, function (result) {results.push(result); //存放每次任务的结果if (results.length === items.length) { //当结果总数与参数总数相等则任务完成,调用final()final(results[results.length - 1]);}})
});

3,流程控制之串,并行结合

// 3,流程控制之串,并行结合(可以通过调节并行执行的最大任务数量来达到资源与效率的最佳平衡)
var items = [1, 2, 3, 4, 5, 6]; //所有任务的参数
var results = []; //每个任务存放结果的地方
var running = 0; //正在运行的任务数量
var limit = 2; //允许并行执行至多任务数量function async (arg, callback) { //任务console.log('参数为 ' + arg + ' , 1秒后返回结果');setTimeout(function () {callback(arg * 2);}, 1000);
}function final(value) { //任务列表完成后执行的函数console.log('完成: ', value);
}function launcher() { //任务发射器(串,并行执行)while (running < limit && items.length > 0) {//利用循环来挂起异步任务,一次最多挂起 limit 次异步任务,有异步任务执行完成后递归launcher再次用此循环挂起异步任务var item = items.shift();//取出第一个参数并从参数列表中删除async (item, function (result) {results.push(result);//存入每次任务的结果running--;//正在运行的任务数量-1if (items.length > 0) {//如果参数列表还有参数则递归launcher()以开始另一个任务launcher();} else if (running == 0) {//正在运行的任务数量等于0时结束递归并调用final()final(results);}});running++;//正在运行的任务数量+1,注意:此行代码为同步任务内容会在异步任务async()前执行,因为同步任务结束后才会检查执行异步任务}
}launcher(); //开启任务发射器

@沉木

JS_异步任务之流程控制相关推荐

  1. JavaScript异步流程控制的前世今生

    js的流程控制老大难问题就是异步回调. 一个流程过程,往往会出现回调地狱,这个回调异步控制就被提上研究得议程. 目前有实现的回调流程有以下几种 回调函数实现 事件监听 发布订阅 Promise/A+ ...

  2. nodejs异步流程控制

    场景: 1.图片上传服务器 2.图片写入磁盘 3.图片写入数据库 在nodejs里面这三种方式都是异步操作,不想java其他语言同步进行,这就需要对异步流程进行控制,保证1,2,3逐步进行.有可能1还 ...

  3. 某大型银行深化系统技术方案之八:核心层之异步流程控制机制

    传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 核心层 核心层主要提供后台业务集中处理中最基本.共性的信息处理.流程调度和相关的管理功能 ...

  4. nodejs异步流程控制co 模块

    万恶的回调 对前端工程师来说,异步回调是再熟悉不过了,浏览器中的各种交互逻辑都是通过事件回调实现的,前端逻辑越来越复杂,导致回调函数越来越多,同时 nodejs 的流行也让 javascript 在后 ...

  5. Node.js 模块之Nimble流程控制

    NodeJS异步的特性有时候会导致程序非常的难看,回调一层套着一层,这个时候就要用流程控制模块来控制究竟是同步还是异步了. Nimble是一个轻量.可移植的函数式流程控制模块.经过最小化和压缩后只有8 ...

  6. 流程控制: jQ Deferred 与 ES6 Promise 使用新手向入坑!

    谢谢n͛i͛g͛h͛t͛i͛r͛e͛大大指出的关于Promise中catch用的不到位的错误,贴上大大推荐的文章Promise中的菜鸟和高阶错误,文章很详细说明了一些Promise使用中的错误和指导. ...

  7. 【Go】二、Go流程控制

    文章目录 Go流程控制 1.条件语句IF 2.条件语句switch 3.条件语句select 4.循环语句for 5.循环语句range 6.循环控制goto.break.... Go流程控制 1.条 ...

  8. Activiti流程控制框架

    Activiti概述 Activiti5是由Alfresco软件发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流程语言框架.Act ...

  9. 在C++程序中添加逻辑流程控制

    在C++ 程序中添加逻辑流程控制          问题的引出 在计算机程序中,除了常见的执行流程控制,还有逻辑流程控制:有时,执行流程即为逻辑流程,但在大多数情况下还是有所区别的,例如,假定有一个W ...

最新文章

  1. 华为:HarmonyOS 即将开源!
  2. 删除coredump内容
  3. PHP exec xargs 不执行,关于 ‘--exec’ 参数( find 命令)及介绍 ‘xargs ’命令区别(新版)...
  4. [转载]Yacc基础
  5. 一个ApplicationContext.xml的配置
  6. Matlab与高等数学
  7. 单片机c语言篮球比分_基于单片机的篮球比赛计时计分器的设计
  8. android 流量统计工具,Android 统计应用流量的使用情况
  9. python socket udp_python网络-Socket之udp编程(24)
  10. cocos2dx 学习笔记5 关于屏幕大小的问题
  11. 字符串函数rpartition与partition
  12. Oracle DBHelper 第二版
  13. Node.js连接MySQL数据库
  14. Python比较文件不同
  15. js实现复制input隐藏域的取巧做法
  16. 桃源网盘php,桃源居业主自建论坛 - Powered by PHPWind
  17. win7下运行.php,Win7下在IIS7中配置PHP的FastCGI支持_笔记
  18. HTML表格翻页效果-洋葱先生-杨少通
  19. 酒店预订分销系统和分销商
  20. 微信小程序云开发CMS中WebHook功能的使用方法

热门文章

  1. vtkSuperquadricSource:创建以原点为中心的多边形超二次曲面
  2. 网络安全系列之三十九 在Linux中配置访问控制列表ACL
  3. 深入理解:overflow:hidden——溢出,坍塌,清除浮动
  4. jQuery跨域,添加自定义头部header
  5. Java Web学习总结(20)——基于ZooKeeper的分布式session实现
  6. BI/数据仓库/数据分析 基础入门:一些常见概念解释
  7. 将byte数组写进文件,指定buffer size
  8. win10怎么进入修复计算机,windows10安全模式怎么修复系统_win10安全模式如何修复电脑...
  9. html相对位置置顶,css定位(position)属性怎么用?
  10. loadedapk.java_android,_java.lang.ClassCastException: android.os.BinderProxy,android - phpStudy