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 textlimit 显示用户输入的字符数 限制用户输入的字符数
May 14 Javascript
js内置对象 学习笔记
Aug 01 Javascript
JS动态添加option和删除option(附实例代码)
Apr 01 Javascript
JS.getTextContent(element,preformatted)使用介绍
Sep 21 Javascript
jquery ajax 简单范例(界面+后台)
Nov 19 Javascript
js实现数组去重、判断数组以及对象中的内容是否相同
Nov 29 Javascript
利用JS进行图片的切换即特效展示图片
Dec 03 Javascript
获取select元素被选中的文本内容的js代码
Jan 29 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
Jul 29 Javascript
js去除浏览器默认底图的方法
Jun 08 Javascript
js中bool值的转换及“&&”、“||”、 “!!”详解
Dec 21 Javascript
JavaScript实现轮播图效果
Oct 30 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
php4的session功能评述(二)
2006/10/09 PHP
php中支持多种编码的中文字符串截取函数!
2007/03/20 PHP
Apache环境下PHP利用HTTP缓存协议原理解析及应用分析
2010/02/16 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
浅谈PHP错误类型及屏蔽方法
2017/05/27 PHP
点击文章内容处弹出页面代码
2009/10/01 Javascript
jQuery 性能优化手册 推荐
2010/02/23 Javascript
JavaScript实用技巧(一)
2010/08/16 Javascript
DD_belatedPNG,IE6下PNG透明解决方案(国外)
2010/12/06 Javascript
jQuery实现简单网页遮罩层/弹出层效果兼容IE6、IE7
2014/06/16 Javascript
js字符串完全替换函数分享
2014/12/03 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
2015/12/07 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
微信小程序 跳转方式总结
2017/04/20 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
2018/03/02 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
ES5和ES6中类的区别总结
2020/12/21 Javascript
python 自动提交和抓取网页
2009/07/13 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
用pyqt5 给按钮设置图标和css样式的方法
2019/06/24 Python
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
2020/10/21 Python
城建学院毕业生自荐信
2014/01/31 职场文书
预备党员2014全国两会学习心得体会
2014/03/10 职场文书
党员对照检查材料
2014/09/22 职场文书
违反交通安全法检讨书
2014/10/24 职场文书
先进党支部事迹材料
2014/12/24 职场文书
区域销售经理岗位职责
2015/04/02 职场文书
2015年度招聘工作总结
2015/05/28 职场文书
电影雨中的树观后感
2015/06/15 职场文书
恋恋笔记本观后感
2015/06/16 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
致三级跳运动员加油稿
2015/07/21 职场文书
JMeter对MySQL数据库进行压力测试的实现步骤
2022/01/22 MySQL
如何在Python中妥善使用进度条详解
2022/04/05 Python