2008年3月更新:
本系列由于某些原因没有继续完成,可能等过一段时间再完成。
http://qiezi.javaeye.com/blog/163182的comments中提到的async_call与这里的思路有类似之处,虽然那是在讨论ErLang。



众所周知,AJAX虽然提高了用户体验,并提出了一种创新的web应用架构模式,但是也带来了一个问题,就是异步编程非常复杂。

单纯一个异步XHR调用或许还不算什么,但当多个XHR交织的时候,复杂性就指数级上升。例如,考虑这样一个人造的例子:

一个股票页面(带劲吧?)

首先从一个数据源读取当前用户所持有的股票种类和数量。

然后读取这些股票的当前价格。由于用户可能持有不同市场的股票(如中国A股、中国B股、香港股票、NADQ……),每个市场数据来自不同的xml源,其格式可能不同。

每个xml源可能使用不同的xslt来转换到html片段,比如中国股票与NADQ股票就用不同的xslt来转换。但有些可能共用相同的xslt,如A股和B股的格式差不多,所以用同样的xslt转换。又,香港股票xml源是首先用一个xslt转换成与A股和B股一样的xml格式,然后再用前述的xslt转换为html片段。

页面还会根据所有数据计算出用户的当前在每个市场上市值,以及总市值。


好了,以上这些,如果用传统的异步方式做,你会看到多少callback漫天飞舞呢?

而且我们知道,异步callback是非常难以调试和跟踪的,你经常不知道问题出在哪里,而且很多时候异步问题是很难重现的。


如果异步编程能像同步编程一样清晰,一样易于调试,那该多好!


2005年年底的时候,我突发奇想,借鉴Java 1.5新增的Future类,揉合JavaScript的特性,创造了AJAX的Future编程模式,使得可以用同步编程的编码方式进行异步编程,并可在同步和异步下自由切换,在同步状态下进行业务测试,保证业务实现的正确性,然后切换到异步,进行网络和负载的测试!

在以后的数天里,我会将这种方法与大家共享,也希望大家能共同验证这一模式的可行性!
评论
winterwolf 2007-07-05
还是用一个请求获得数据简单

从多个数据源获得数据并加工的事情 交给服务器吧
legend 2007-07-05
怎么还没看到楼主大作?
zhourenjian 2007-06-12
Hax,

该是时候贴点东西(即使未完成,也聊胜于无)上来了,大家等了比较长时间了。
zhourenjian 2007-06-12
smaviller 写道


我觉得Hax楼主所说的,和上述两个链接谈及的技术完全不一样。

从我个人角度看,我认为,Hax考虑更多的是参考Java 5 中Cocurrent的API设计,在JavaScript中类似地使用Future模式。
legend 2007-06-10
不能理解,太高深了,期待楼主解答。
birdjavaeye 2007-06-10
嗯,重新解析js,或者说编译的方法,也就是我前面提到的思路,差别只是具体如何实现。
但这种方式需要深入研究。同步的写法,是调用一个函数,等待返回,拿到返回值,继续执行。而实际是异步执行,setTimeout、XmlHttp、onclick等等都可能会有回调。
为了保证语义,不是被调用函数的那些回调都必须被屏蔽。否则就好像,被调用函数包含了其他回调的功能,这就改变了被调用函数的语义和作用。
屏蔽不容易,继续深入的话,最后就变成了一个纯粹的没有回调的单线程,用做计算可以,但用于界面就不切实际了
然而用于计算,基本没有异步的情况…

保持同步语义,而又不失灵活性,还是等ie、firefox都支持多线程吧。不过那样又有多线程本身的复杂性了。。。
jindw 2007-06-09
异步变同步,我能想到的方法只有两种。
1.采用mozilla新版本支持的线程处理函数。
2.代码编译。

第一种方法的弊端:目前还局限于mozilla,非正式标准。
第二种方法:编译麻烦,而且,好像也只能整站编译。基于它的实现很难作为类库使用。

不知道hax的实现思路如何?
能否透漏一点?
jindw 2007-06-09
smaviller 写道
国外已经有人实现这种特性,但是需要重新解析js,而且有一定的限制

在那里?别放冷枪嘛。给出个地址来,也让我们好研究研究。别光掉人胃口。
不给地址名字总该透漏一下吧:(
smaviller 2007-06-09
国外已经有人实现这种特性,但是需要重新解析js,而且有一定的限制
fuhao9611 2007-06-05
LZ加油,期待ing~~~!
hax 2007-06-04
正在赶工中。。。
笨笨狗 2007-06-04
赶紧放出来吧,等几天了都……
andot 2007-06-04
期待 hax 的大作!
birdjavaeye 2007-06-04
还有其他办法?说说看
要支持ie&firefox, windows&linux哦
hax 2007-06-04
birdjavaeye bingo! 不过并不需要分析源代码,有其他途径可以达到。
birdjavaeye 2007-06-01
hax 写道
jindw 写道


是有一点类似。不过:

1. 我主要从javascript本身出发,并不限于remote调用的异步,也可以针对setTimeout之类的异步。
2. 针对result的join,我原来确实也是有类似的做法,即有若干个task,然后可以顺序化或并行化,有点像排一个flow。但是后来我觉得这样还是不够,程序员还是要被迫使用一种新的概念和编程模式。我希望程序员能像处理一般的程序那样——即“异步”只是背后发生的,对于程序员可以透明。程序员写出的是很easy的程序,但是通过某种方式,Future模式能透明的把它转换为实际上以异步方式执行。

这样的代码
function go() {
  a();
  b(x, y, z, go2); // 给回调传结果的函数
}
function go2(result) {
  c(result);
}

要能不改变b函数,而直接写成类似
function go() {
  a();
  var result = b();
  c(result);
}

同时基于js单线程特性、用户体验、跨浏览器这些前提,基本上只有一种方法,就是 自动 按照程序员写的后面那种代码 生成 前面那种代码。
程序员这么写:
function go() {
  a();
  var result = $async(b, x, y, z, $callback);
  c(result);
}

然后 go = $sync(go);就自动生成代码
function go() {
  a();
  b(x, y, z, $temp1);
}
function $temp1(result) {
  c(result);
}


而实现方式也不难:利用firefox和ie都支持的Function.prototype.toString,就是在运行时能得到一个方法的源代码。
这个源代码是语法正确的,只要分析一下格式,生成其他代码就可以了。

计划在objot库21版中提供这种代码分析和生成的功能,并用它来实现aop和模拟多线程(就类似前面举的例子)
birdjavaeye 2007-06-01
hax 写道

非也,本身许多东西是同步的,但是它依赖异步的结果,导致本来可同步执行的内容必须callback。请考虑我前述的例子。

既然许多东西都是同步的,那依赖哪些异步的东西呢?主要的也就是XmlHttp和event handler,设计上很容易将他们和同步的分开
hax 2007-06-01
jindw 写道


是有一点类似。不过:

1. 我主要从javascript本身出发,并不限于remote调用的异步,也可以针对setTimeout之类的异步。
2. 针对result的join,我原来确实也是有类似的做法,即有若干个task,然后可以顺序化或并行化,有点像排一个flow。但是后来我觉得这样还是不够,程序员还是要被迫使用一种新的概念和编程模式。我希望程序员能像处理一般的程序那样——即“异步”只是背后发生的,对于程序员可以透明。程序员写出的是很easy的程序,但是通过某种方式,Future模式能透明的把它转换为实际上以异步方式执行。
hax
搜索本博客
存档
最新评论