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的$.event.fix函数统一浏览器event事件处理
Dec 21 Javascript
编写Js代码要注意的几条规则
Sep 10 Javascript
TimergliderJS 一个基于jQuery的时间轴插件
Dec 07 Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
Apr 16 Javascript
jquery实现下拉菜单的二级联动利用json对象从DB取值显示联动
Mar 27 Javascript
10个JavaScript中易犯小错误
Feb 14 Javascript
全面解析Bootstrap中scrollspy(滚动监听)的使用方法
Jun 06 Javascript
BootStrap 轮播插件(carousel)支持左右手势滑动的方法(三种)
Jul 07 Javascript
详解如何在你的Vue项目配置vux
Jun 04 Javascript
Vue实现简单分页器
Dec 29 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
May 22 Javascript
Node.JS获取GET,POST数据之queryString模块使用方法详解
Feb 06 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
DC动画很好看?新作烂得令人发指,名叫《红色之子》
2020/04/09 欧美动漫
php获取根域名方法汇总
2014/10/28 PHP
php使用pear_smtp发送邮件
2016/04/15 PHP
一个简单的php MVC留言本实例代码(必看篇)
2016/09/22 PHP
curl 出现错误的调试方法(必看)
2017/02/13 PHP
用户注册常用javascript代码
2009/08/29 Javascript
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
页面只有一个text的时候,回车自动submit的解决方法
2010/08/12 Javascript
js实现感应鼠标图片透明度变化的方法
2015/02/20 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
jQuery插件boxScroll实现图片轮播特效
2015/07/14 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
jQuery时间插件jquery.clock.js用法实例(5个示例)
2016/01/14 Javascript
Vue.js动态添加、删除选题的实例代码
2016/09/30 Javascript
jQuery通过ajax快速批量提交表单数据
2016/10/25 Javascript
基于scrapy实现的简单蜘蛛采集程序
2015/04/17 Python
Python学习pygal绘制线图代码分享
2017/12/09 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
2019/06/27 Python
Pyqt QImage 与 np array 转换方法
2019/06/27 Python
python查看数据类型的方法
2019/10/12 Python
python 消费 kafka 数据教程
2019/12/21 Python
如何将PySpark导入Python的放实现(2种)
2020/04/26 Python
Python pip使用超时问题解决方案
2020/08/03 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
英国顶级水晶珠宝零售商之一:Tresor Paris
2019/04/27 全球购物
丝芙兰墨西哥官网:Sephora墨西哥
2020/05/30 全球购物
软件缺陷的分类都有哪些
2014/08/22 面试题
个人求职简历的自我评价范文
2013/10/09 职场文书
超市中秋节活动方案
2014/02/12 职场文书
公司合作协议书范本
2014/04/18 职场文书
公司晚会策划方案
2014/05/17 职场文书
高一军训的心得体会
2014/09/01 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
2015年员工工作总结范文
2015/04/08 职场文书
GO语言字符串处理函数之处理Strings包
2022/04/14 Golang