JavaScript 异步调用框架 (Part 2 - 用例设计)


Posted in Javascript onAugust 03, 2009

传递回调
我们首先要考虑的一个问题是,如何传递回调入口。在最传统的XHR调用当中,回调函数会被作为最后一个参数传递给异步函数:

function asyncOperation(argument, callback)

在参数相当多的时候,我们可以把参数放到一个JSON里面,这样参数就如同具名参数一样,可以通过参数名选择性的传递参数,不传递的参数相当于使用默认值。这是从Prototype开始就流行起来的做法:
function asyncOperation(argument, options)

然而这两种做法都有一个坏处,就是把同步函数改为异步函数(或同步异步混合函数)时,必须显式地修改函数签名,在最后增加一个(或多个)参数。

由于在调用栈的底层引入异步函数对我们来说太常见了,为此可能要更改一大堆上层调用函数签名的成本实在是太高了,所以我们还是想一个不用修改函数签名的做法吧。

在这里我参考了.NET Framework的IAsyncResult设计,把异步操作有关的一切信息集中到一个对象上来,从而避免了对函数签名的修改。在此,我们假设一个异步函数的调用原型是这样子的:

function asyncOperation(argument) { 
operation = new Async.Operation(); 
setTimeout(function() { operation.yield("hello world"); }, 1000); 
return operation; 
}

在这段代码里,我们返回了一个Operation对象,用于将来传递回调函数。同时,我们通过setTimeout模拟了异步返回结果,而具体的返回方式就是yield方法。

接着,我们还要设计传递回调函数的方法。由于我们不能好像C#那样重载+=运算符,所以只能用函数传递回调函数:

var operation = asyncOperation(argument); 
operation.addCallback(function(result) { alert(result); });

在C#里面做这样的设计是不安全的,因为在异步操作可能在添加回调之前就完成了。但在JavaScript里面这样写是安全的,因为JavaScript是单线程的,紧接着asyncOperation的同步addCallback必然先执行,asyncOperation中的异步yield必然后执行。

调用顺序
可能有人要问,如果用户使用同步的方式来调用yield,这时候执行顺序不一样依赖于yield的实现吗?没错,不过yeild是在框架中一次性实现的,我们只要把它做成异步的就可以了,这样即使对它进行同步调用,也不影响执行顺序:

function psudoAsyncOperation(argument) { 
operation = new Async.Operation(); 
operation.yield("hello world"); 
return operation; 
} 
var operation = asyncOperation(argument); 
operation.addCallback(function(result) { alert(result); });

就算把代码写成这个样子,我们也能确保addCallback先于yield的实际逻辑执行。

事后回调
有时候,框架的使用者可能真的写出了先yield后addCallback的代码。这时候,我认为必须保证addCallback中添加的回调函数会被立即触发。因为用户添加这个回调函数,意味着他期望当异步操作有结果时通知这个回调函数,而这与添加回调函数时异步操作是否完成无关。为此,我们再添加一个用例:

function psudoAsyncOperation(argument) { 
operation = new Async.Operation(); 
operation.yield("hello world"); 
return operation; 
} 
var operation = asyncOperation(argument); 
setTimeout(function() { 
operation.addCallback(function(result) { alert(result); }); 
}, 1000);

小结
到这里,我们就设计好了一个名为Async.Operation的异步操作对象,具体如何实现关键的yield方法和addCallback方法将在下一篇文章讲述如果。
Javascript 相关文章推荐
网页前台通过js非法字符过滤代码(骂人的话等等)
May 26 Javascript
jQuery表格行换色的三种实现方法
Jun 27 Javascript
javascript开发技术大全 第4章 直接量与字符集
Jul 03 Javascript
可选择和输入的下拉列表框示例
Nov 05 Javascript
调用DOM对象的focus使文本框获得焦点
Feb 19 Javascript
JS的get和set使用示例
Feb 20 Javascript
javascript+canvas制作九宫格小程序
Dec 28 Javascript
js游戏人物上下左右跑步效果代码分享
Aug 28 Javascript
跟我学习javascript的prototype,getPrototypeOf和__proto__
Nov 17 Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
Feb 18 Javascript
使用vue构建一个上传图片表单
Jul 04 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
Javascript 验证上传图片大小[客户端]
Aug 01 #Javascript
You might like
全国FM电台频率大全 - 9 上海市
2020/03/11 无线电
索尼ICF-SW100收音机评测
2021/03/02 无线电
php UTF-8、Unicode和BOM问题
2010/05/18 PHP
PHP学习散记_编码(json_encode 中文不显示)
2011/11/10 PHP
CentOS 安装 PHP5.5+Redis+XDebug+Nginx+MySQL全纪录
2015/03/25 PHP
thinkPHP3.2简单实现文件上传的方法
2016/05/16 PHP
php中get_magic_quotes_gpc()函数说明
2017/02/06 PHP
PHP简单实现记录网站访问量功能示例
2018/06/06 PHP
javascript web对话框与弹出窗口
2009/02/22 Javascript
jquery 学习之二 属性相关
2010/11/23 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
使用Sticky组件实现带sticky效果的tab导航和滚动导航的方法
2016/03/22 Javascript
vue.js入门教程之绑定class和style样式
2016/09/02 Javascript
微信js-sdk分享功能接口常用逻辑封装示例
2016/10/13 Javascript
Nodejs基于LRU算法实现的缓存处理操作示例
2017/03/17 NodeJs
如何在AngularJs中调用第三方插件库
2017/05/21 Javascript
浅谈node中的cluster集群
2018/06/02 Javascript
[51:26]VP vs VG 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python脚本爬取字体文件的实现方法
2017/04/29 Python
对matplotlib改变colorbar位置和方向的方法详解
2018/12/13 Python
Python Selenium 之数据驱动测试的实现
2019/08/01 Python
Tensorflow训练模型越来越慢的2种解决方案
2020/02/07 Python
python中二分查找法的实现方法
2020/12/06 Python
Python wordcloud库安装方法总结
2020/12/31 Python
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
机电专业毕业生推荐信
2013/11/10 职场文书
优秀体育委员自荐书
2014/01/31 职场文书
十八届三中全会学习方案
2014/02/16 职场文书
葬礼司仪主持词
2014/03/31 职场文书
孔庙导游词
2015/02/04 职场文书
教师工作表现自我评价
2015/03/05 职场文书
2015年加油站工作总结
2015/05/13 职场文书
大学开学感言
2015/08/01 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
Python序列化与反序列化相关知识总结
2021/06/08 Python
我的收音机情缘
2022/04/05 无线电