JavaScript,异步调用,框架
web前端-js教程
传递回调 我们首先要考虑的一个问题是,如何传递回调入口。在最传统的XHR调用当中,回调函数会被作为最后一个参数传递给异步函数:
问答php源码,ubuntu下编译twrp,python爬虫王者战绩,lis()php,南昌seo营销lzw
function asyncOperation(argument, callback)在参数相当多的时候,我们可以把参数放到一个JSON里面,这样参数就如同具名参数一样,可以通过参数名选择性的传递参数,不传递的参数相当于使用默认值。这是从Prototype开始就流行起来的做法:
源码挂q,vscode无法识别git,ubuntu 网易课程,sts部署远程tomcat,梅花爬虫,php 提取汉字,行唐seo搜索优化价格,产品发布 网站 模板,帝国cms 途牛 模板lzw
function asyncOperation(argument, options)然而这两种做法都有一个坏处,就是把同步函数改为异步函数(或同步异步混合函数)时,必须显式地修改函数签名,在最后增加一个(或多个)参数。
磁力链接在线播放工具 源码,vscode终端显示异常,ubuntu安装pwn,部署tomcat时报错,爬虫tdk,php 对象 添加属性,如何做seo精华,08影院视频网站最新源码,手机端开发网站模板lzw
由于在调用栈的底层引入异步函数对我们来说太常见了,为此可能要更改一大堆上层调用函数签名的成本实在是太高了,所以我们还是想一个不用修改函数签名的做法吧。 在这里我参考了.NET Framework的IAsyncResult设计,把异步操作有关的一切信息集中到一个对象上来,从而避免了对函数签名的修改。在此,我们假设一个异步函数的调用原型是这样子的:
function asyncOperation(argument) {在这段代码里,我们返回了一个Operation对象,用于将来传递回调函数。同时,我们通过setTimeout模拟了异步返回结果,而具体的返回方式就是yield方法。
operation = new Async.Operation();
setTimeout(function() { operation.yield("hello world"); }, 1000);
return operation;
}
接着,我们还要设计传递回调函数的方法。由于我们不能好像C#那样重载+=运算符,所以只能用函数传递回调函数:
var operation = asyncOperation(argument);在C#里面做这样的设计是不安全的,因为在异步操作可能在添加回调之前就完成了。但在JavaScript里面这样写是安全的,因为JavaScript是单线程的,紧接着asyncOperation的同步addCallback必然先执行,asyncOperation中的异步yield必然后执行。
operation.addCallback(function(result) { alert(result); });
调用顺序
可能有人要问,如果用户使用同步的方式来调用yield,这时候执行顺序不一样依赖于yield的实现吗?没错,不过yeild是在框架中一次性实现的,我们只要把它做成异步的就可以了,这样即使对它进行同步调用,也不影响执行顺序:
function psudoAsyncOperation(argument) {就算把代码写成这个样子,我们也能确保addCallback先于yield的实际逻辑执行。
operation = new Async.Operation();
operation.yield("hello world");
return operation;
}
var operation = asyncOperation(argument);
operation.addCallback(function(result) { alert(result); });
事后回调
有时候,框架的使用者可能真的写出了先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方法将在下一篇文章讲述如果。