JavaScript 异步调用框架 (Part 3 - 代码实现)


Posted in Javascript onAugust 04, 2009

类结构
首先我们来搭一个架子,把需要用到的似有变量都列出来。我们需要一个数组,来保存回调函数列表;需要一个标志位,来表示异步操作是否已完成;还可以学IAsyncResult,加一个state,允许异步操作的实现者对外暴露自定义的执行状态;最后加一个变量保存异步操作结果。

Async = { 
Operation: { 
var callbackQueue = []; 
this.result = undefined; 
this.state = "waiting"; 
this.completed = false; 
} 
}

addCallback方法
接下来,我们要实现addCallback方法,它的工作职责很简单,就是把回调函数放到callbackQueue中。此外,如果此时completed为true,说明异步操作已经yield过了,则立即调用此回调。
this.yield = function(callback) { 
callbackQueue.push(callback); 
if (this.completed) { 
this.yield(this.result); 
} 
return this; 
}

我们假设yield方法会把callbackQueue中的回调函数逐个取出来然后调用,因此如果compeleted为true,则使用已有的result再调用一次yield就可以了,这样yield自然会调用这次添加到callbackQueue的回调函数。
至于最后的return this;,只是为了方便jQuery风格的链式写法,可以通过点号分隔连续添加多个回调函数:
asyncOperation(argument) 
.addCallback(firstCallback) 
.addCallback(secondCallback);

yield方法
最后,我们要实现yield方法。它需要将callbackQueue中的回调函数逐个取出来,然后都调用一遍,并且保证这个操作是异步吧。
this.yield = function(result) { 
var self = this; 
setTimeout(function() { 
self.result = result; 
self.state = "completed"; 
self.completed = true; 
while (callbackQueue.length > 0) { 
var callback = callbackQueue.shift(); 
callback(self.result); 
} 
}, 1); 
return this; 
}

通过使用setTimeout,我们确保了yield的实际操作是异步进行的。然后我们把用户传入yield的结果及相关状态更新到对象属性之上,最后遍历callbackQueue调用所有的回调函数。
小结
这样我们就做好了一个简单的JavaScript异步调用框架,完整的代码可以看这里:异步调用框架Async.Operation。
这个框架能够很好的解决调用栈中出现同步异步操作并存的情况,假设所有函数都返回Async.Operation,框架的使用者可以使用一种统一的模式来编写代码,处理函数返回,而无需关心这个函数实际上是同步返回了还是异步返回了。
对于串行调用多个异步函数的情况,我们现在可以用嵌套addCallback的方式来书写,但随着嵌套层数的增多,代码会变得越来越不美观:
firstAsyncOperation().addCallback(function() { 
secondAsyncOperation().addCallback(function() { 
thirdAsyncOperation().addCallback(function() { 
finalSyncOperation(); 
}); 
}); 
});

我们能否把嵌套形式改为jQuery风格的链式写法呢?这是我们接下来要思考的问题,如果你不希望错过相关讨论的话
Javascript 相关文章推荐
jQuery示例收集
Nov 05 Javascript
使用jquery局部刷新(jquery.load)从数据库取出数据
Jan 22 Javascript
jQuery中Dom的基本操作小结
Jan 23 Javascript
JavaScript中的null和undefined区别介绍
Jan 01 Javascript
禁止按回车键提交表单的方法
Jun 11 Javascript
js实现浮动在网页右侧的简洁QQ在线客服代码
Sep 04 Javascript
js实现简洁的TAB滑动门效果代码
Sep 06 Javascript
详谈JavaScript的闭包及应用
Jan 17 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
Jul 03 Javascript
vue中post请求以a=a&b=b 的格式写遇到的问题
Apr 27 Javascript
layui实现根据table数据判断按钮显示情况的方法
Sep 26 Javascript
webpack+vue.js构建前端工程化的详细教程
May 10 Javascript
JavaScript 异步调用框架 (Part 2 - 用例设计)
Aug 03 #Javascript
JavaScript 异步调用框架 (Part 1 - 问题 & 场景)
Aug 03 #Javascript
jQuery 相关控件的事件操作分解
Aug 03 #Javascript
利用javascript实现一些常用软件的下载导航
Aug 03 #Javascript
jQuery 隔行换色 支持键盘上下键,按Enter选定值
Aug 02 #Javascript
一句话JavaScript表单验证代码
Aug 02 #Javascript
JavaScript 关键字屏蔽实现函数
Aug 02 #Javascript
You might like
拼音码表的生成
2006/10/09 PHP
php 过滤危险html代码
2009/06/29 PHP
深入PHP异步执行的详解
2013/06/03 PHP
深入PHP5中的魔术方法详解
2013/06/17 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之二
2011/12/31 Javascript
replace()方法查找字符使用示例
2013/10/28 Javascript
jQuery实现数字加减效果汇总
2014/12/16 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
让网站自动生成章节目录索引的多个js代码
2018/01/07 Javascript
微信小程序实现MUI数字输入框效果
2018/01/31 Javascript
在Python的struct模块中进行数据格式转换的方法
2015/06/17 Python
利用PyInstaller将python程序.py转为.exe的方法详解
2017/05/03 Python
Python编程之string相关操作实例详解
2017/07/22 Python
pytorch + visdom 处理简单分类问题的示例
2018/06/04 Python
Python提取特定时间段内数据的方法实例
2019/04/01 Python
python爬虫刷访问量 2019 7月
2019/08/01 Python
Python如何实现动态数组
2019/11/02 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
django xadmin 管理器常用显示设置方式
2020/03/11 Python
Python Django中间件使用原理及流程分析
2020/06/13 Python
出口公司经理求职简历中的自我评价
2013/10/13 职场文书
cf战队收人广告词
2014/03/14 职场文书
品酒会策划方案
2014/05/26 职场文书
授权委托书样本及填写说明
2014/09/19 职场文书
个人反四风对照检查材料思想汇报
2014/09/23 职场文书
大学生毕业评语
2014/12/31 职场文书
文案策划岗位职责
2015/02/11 职场文书
初级职称评定工作总结
2015/08/13 职场文书
导游词之包公祠
2019/11/25 职场文书
一文搞懂如何实现Go 超时控制
2021/03/30 Python
一篇文章带你复习java知识点
2021/06/28 Java/Android
Win11绿屏怎么办?Win11绿屏死机的解决方法
2021/11/21 数码科技
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
2022/05/25 SQL Server
V Rising 服务器搭建图文教程
2022/06/16 Servers