JavaScript异步调用框架用例设计

开发 前端
本文描述一个JavaScript异步调用框架的用例设计。这个框架用例最好能够统一同步异步调用的接口,同时具体调用顺序与实现方式无关。

在上一篇文章里说到,我们要设计一个JavaScript异步调用框架,***能够统一同步异步调用的接口,同时具体调用顺序与实现方式无关。那么我们现在就来设计这样一个框架的用例。

传递回调

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

  1. function asyncOperation(argument, callback) 

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

  1. function asyncOperation(argument, options) 

然而这两种做法都有一个坏处,就是把同步函数改为异步函数(或同步异步混合函数)时,必须显式地修改函数签名,在***增加一个(或多个)参数。这是JavaScript异步调用种需要考虑的问题。

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

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

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

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

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

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

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

调用顺序

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

  1. function psudoAsyncOperation(argument) {  
  2.   operation = new Async.Operation();  
  3.   operation.yield("hello world");  
  4.   return operation;  
  5. }  
  6. var operation = asyncOperation(argument);  
  7. operation.addCallback(function(result) { alert(result); }); 

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

事后回调

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

  1. function psudoAsyncOperation(argument) {  
  2.   operation = new Async.Operation();  
  3.   operation.yield("hello world");  
  4.   return operation;  
  5. }  
  6. var operation = asyncOperation(argument);  
  7. setTimeout(function() {  
  8.   operation.addCallback(function(result) { alert(result); });  
  9. }, 1000); 

小结

到这里,我们就设计好了一个名为Async.Operation的异步操作对象。JavaScript异步调用的方法将对这个对象进行操作。

【编辑推荐】

  1. JavaScript异步调用框架问题描述
  2. 浅谈如何用Javascript+VML实现流程设计器
  3. 常用的JavaScript验证正则表达式
  4. 给JavaScript初学者的24个小窍门
  5. JavaScript中关于Cookie的详细介绍
责任编辑:yangsai 来源: Cat in dotNET
相关推荐

2009-07-01 13:58:00

JavaScript异

2009-07-01 14:23:46

JavaScript异

2009-07-01 14:37:14

JavaScript异

2009-07-01 14:31:01

JavaScript异

2009-10-20 16:48:30

C#委托

2009-12-21 14:10:26

WCF异步调用

2009-11-09 10:50:30

WCF异步调用

2009-11-06 15:54:15

WCF异步调用

2010-02-22 13:28:05

WCF异步调用

2009-08-21 11:24:16

C#异步调用

2009-12-07 14:35:42

WCF异步调用

2012-10-29 10:59:27

Windows 8

2009-12-07 14:26:47

WCF异步调用

2021-03-29 09:26:44

SpringBoot异步调用@Async

2011-03-02 08:57:22

jQueryJavaScript

2010-01-11 17:24:19

VB.NET异步调用

2009-11-09 15:49:01

WCF异步调用

2009-08-21 11:02:55

C#异步调用

2020-01-02 16:30:02

Spring BootJava异步请求

2010-02-25 09:13:34

WCF异步调用
点赞
收藏

51CTO技术栈公众号