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 相关文章推荐
用javascript动态调整iframe高度的代码
Apr 10 Javascript
JQuery Tips(3) 关于$()包装集内元素的改变
Dec 14 Javascript
解析jQuery与其它js(Prototype)库兼容共存
Jul 04 Javascript
jquery处理json对象
Nov 03 Javascript
使用javascript获取页面名称
Dec 23 Javascript
jQuery基于函数重载实现自定义Alert函数样式的方法
Jul 27 Javascript
Angular 2父子组件数据传递之@Input和@Output详解 (上)
Jul 05 Javascript
使用百度地图实现地图网格的示例
Feb 06 Javascript
vue短信验证性能优化如何写入localstorage中
Apr 25 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
Jan 27 jQuery
解决layui动态加载复选框无法选中的问题
Sep 20 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
Dec 09 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
laravel按天、按小时,查询数据的实例
2019/10/09 PHP
使用 PHP Masked Package 屏蔽敏感数据的实现方法
2019/10/15 PHP
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
2013/01/09 Javascript
javascript实现2048游戏示例
2014/05/04 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
浅析jQuery EasyUI中的tree使用指南
2014/12/18 Javascript
jQuery实现仿腾讯视频列表分页效果的方法
2015/08/07 Javascript
jQuery三级下拉列表导航菜单代码分享
2020/04/15 Javascript
jqueryMobile使用示例分享
2016/01/12 Javascript
JavaScript 中的 this 简单规则
2017/09/19 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
[02:22]《新闻直播间》2017年08月14日
2017/08/15 DOTA
[01:03:27]NAVI vs EG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
跟老齐学Python之print详解
2014/09/28 Python
Python日期时间模块datetime详解与Python 日期时间的比较,计算实例代码
2018/09/14 Python
Python 多个图同时在不同窗口显示的实现方法
2019/07/07 Python
django 快速启动数据库客户端程序的方法示例
2019/08/16 Python
python 内置函数汇总详解
2019/09/16 Python
在Django中实现添加user到group并查看
2019/11/18 Python
python2和python3哪个使用率高
2020/06/23 Python
HTML5在canvas中绘制复杂形状附效果截图
2014/06/23 HTML / CSS
巴西最大的家具及装饰用品店:Mobly
2017/10/11 全球购物
Shop Apotheke瑞士:您的健康与美容网上商店
2019/10/09 全球购物
师范大学应届生求职信
2013/11/21 职场文书
九年级科学教学反思
2014/01/29 职场文书
我的梦想演讲稿1000字
2014/08/21 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
秋收起义观后感
2015/06/11 职场文书
消费者投诉书范文
2015/07/02 职场文书
2016年寒假家长评语
2015/10/10 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
创业计划书之书店
2019/09/10 职场文书
css3实现背景图片半透明内容不透明的方法示例
2021/04/13 HTML / CSS
【海涛解说】pis亲自推荐,其实你从来不会玩NW
2022/04/01 DOTA
《杜鹃的婚约》OP主题曲「凸凹」无字幕影像公开
2022/04/08 日漫