这次打算把Jscex好好搞一下了,其实很少会有技术方面的障碍能“轮到”我们去突破,但我觉得Jscex的确有机会,HTML 5、Node.js各个都是红火的玩意儿。前几天我花了两个晚上用半生不熟的中式英语写了一篇自认为比较完整的说明文字放到了Github上的项目首页上,没想到几个小时后便收到了StratifiedJS(一个与Jscex目标有些类似的项目)作者的邮件,提到了一些关于StratifiedJS的事情。我向他咨询了StratifiedJS的某些细节问题,也向他简单介绍了Jscex的实现原理。如今Jscex已经使用BSD授权协议正式发布(中文站也会在近期推出),再进行一些细节上的优化便要开始作推广了。
最近的一次优化便是去除不必要的Delay方法调用。Delay的目的是延迟某段代码的执行时间,确保它只会在合适的时间执行,这对于非“延迟”及有副作用的语言来说十分重要。在F#中Delay方法的签名如下(Jscex与之类似):
// async.Delay
((unit -> Async<'a>) -> Async<'a>)
Delay函数可以不断嵌套,从效果说来讲不会有所区别,例如:
builder.Delay(function () {
return builder.Delay(function () {
return builder.Delay(function () {
return builder.Loop(...);
});
});
});
上面这段代码和直接一个builder.Loop相比不会对结果产生任何影响,但是显然,从生成代码的整洁、美观程度(这涉及到可调试性)及性能都会有所损耗。之前的Jscex编译器会生成不必要的Delay(当然也不会有上面那么夸张),那是因为以前的代码生成器只是直接遍历从UglifyJS解析器那里获得的AST,以此来生成代码。新的编译器重新调整了结构和策略,会先将UglifyJS的AST转化为一个中间形式——我把它叫做Jscex AST,然后再让代码生成器从Jscex AST生成代码。新的生成器在工作时,会略过某些delay节点,直接从它的自节点中生成代码,以此达到去除不必要的Delay方法调用的目的。
举例来说,一个快速排序的Jscex函数:
var bubbleSortAsync = eval(Jscex.compile("async", function (array) {
for (var x = 0; x < array.length; x++) {
for (var y = 0; y < array.length - x; y++) {
var r = $await(compareAsync(array[y], array[y + 1]));
if (r > 0) {
$await(swapAsync(array, y, y + 1));
}
}
}
}));
它会生成如下的代码(与之前的结果相比省去了一些Delay方法调用):
var bubbleSortAsync = (function (array) {
var $_builder_$ = Jscex.builders["async"];
return $_builder_$.Start(this, $_builder_$.Delay(function () {
return $_builder_$.Delay(
function () {
var x = 0;
return $_builder_$.Loop(
function () {
return x < array.length;
},
function () {
x++;
},
$_builder_$.Delay(function () {
return $_builder_$.Delay(
function () {
var y = 0;
return $_builder_$.Loop(
function () {
return y < (array.length - x);
},
function () {
y++;
},
$_builder_$.Delay(function () {
return $_builder_$.Bind(compareAsync(...), function (r) {
return $_builder_$.Delay(
function () {
if (r > 0) {
return $_builder_$.Bind(swapAsync(...), function () {
return $_builder_$.Normal();
});
} else {
return $_builder_$.Normal();
}
});
});
}),
false
);
});
}),
false
);
});
}));
})
当然,Jscex还是有进一步优化的空间。例如包括保留“没有bind操作”的代码块,以及“嵌套Jscex函数”等等。最近一段时间应该会不断有一些更新。如果您在用JavaScript开发异步程序,也不妨一起来使用Jscex吧,它毫无疑问能显著改善您的编程生活。
广告时间:第四届nBazaar技术交流会将于4月23日(本周六)于畅星大厦(上海市浦东新区碧波路888号,地铁二号线张江高科站下,步行10分钟可达)副楼3楼会议厅举行,在此欢迎您的到来,请于下午1点前准时入场。没有报名的朋友也可以现场报名。由于领导支持,我们将在现场送出市场价999元的盛大Bambook一台作为幸运观众的礼品,此外图灵出版社也赞助了十几本图书将会送给积极发言的观众。更多详细信息请参考活动首页。