缘起
作为一个开源项目,社区群众的参与必不可少,Wind.js在这方面做的十分不足。项目发展至今,从代码到所有的文档材料,几乎都是由我一个人完成的。我已经在文档上花费了很大心力,但依然只能写一些最基本的内容,大部分的思考依然只存在与脑海中,这让我倍感无力。而且作为项目的开发者,我也希望可以从更多角度来了解使用者眼中的Wind.js。我知道整个项目的细枝末节,但有些时候我眼里顺理成章的事情,似乎在别人看来并非那么自然。
出于多方面考虑,我决定发起一次有奖征文活动,希望可以借助此次活动加强Wind.js的群众基础,并让互联网上出现更多有关Wind.js的资料,其中优秀的内容也会有机会进入Wind.js官方文档。
活动规则
本次征文活动诚邀Wind.js新老用户参与,要求如下:
- 载体不限:通过个人博客,或是其他能够在互联网上长期访问的载体发布内容。
- 内容不限:可以是入门教程、使用心得、案例介绍、源码评析、意见建议等各类相关内容。
- 形式不限:尽管是“征文”,但除文章之外亦可使用PPT等各类文案形式。
- 数量不限:一人可以在截止日期前提交多份文章。
活动从今天开始,至9月30日结束。完成后请将地址回复于此,亦可通过微博@老赵,所有提交的文章将列于(原文)文末。如果您在创作过程中遇到任何疑问,或想要了解任何关于Wind.js的内容,请加入Wind.js讨论组,或直接发送邮件提问或参与讨论。
评奖方式及奖品
本次活动会邀请业界专家(3到5名),普通群众,以及我本人共同参与投票计分:
- 本人:三票,每票10分。
- 专家:每人三票,每票5分。
- 群众:每人三票,每票1分。
本次活动将设三个级别的奖项:
- 一等奖1名,奖品为价值50元的亚马逊代金券3张。
- 二等讲2名,奖品为价值50元的亚马逊代金券2张。
- 三等奖5名,奖品为价值50元的亚马逊代金券1张。
本次活动奖品由“Wind.js基金”赞助。奖品亦可换成价格相近的礼品,获奖者可自由决定。
如果有这样一段逻辑: //点击按钮 but1.addEvent("click",function(){ alert(“but1”); }); but2.addEvent("click",function(){ alert(“but2”); }); but3.addEvent("click",function(){ alert(“but3”); }); 用windJs应该怎么表示?
对于老赵大神很崇拜也很佩服,在试用了jscex(我还是喜欢这个名字,听起来像是jsex)后,有些疑问,希望老赵大神帮忙解答一下。 对于嵌套的回调来说 比如:
function a(){
dosth(function b (){
dosth(function c(){
});
})
},
用wind来写就是 await(a()); await(b()); await(c()); 这样的表达很清晰自然, 但是这样并不好调试,虽然在出错时会出现编译好的代码,但是出错的断点却只能在eval那行,如果内部有比较复杂的逻辑,出错的地方比较难找 如果用eventProxy,则会简单一些 比如:
proxy.bind('aDone',b)
proxy.bind('bDone',c)
function a(){
proxy.trigger('aDone');
}
function b(){
proxy.trigger('bDone');
}
function c(){
}
希望能听听老赵大神的看法
开始使用Wind.js了, 发现文档有些地方有小bug,
- http://windjs.org/cn/docs/async/binding.html
var seed - 重复
- http://windjs.org/cn/docs/ 「加载模块」 链接失效
用windJs如果有并发怎么表示? 比如: for (var i = 0; i < 10; i++) { await { setTimeout (defer (), 100); setTimeout (defer (), 10); } console.log (“hello”); } 这里的伪代码表示的是,await 等待两个setTimeout并发之后,打印hello 用windJs怎么表示??
@jeffz 留言的时候依据自己很早前的一次经验,可能并不适用于目前wind.js。那次我在使用时出现了一个错误,但是游览器的断点停止在了eval(Jscex.compile这一行,没有标明出错的原因,并把所需要complie的内容全部标黄了。 这一次经历对我造成不太好的感觉。不过关于错误报告,目前好象是在console里面有把编译阶段出现的错误类型和大致内容写出来,这样挺好的。
@jeffz 留言的时候依据自己很早前的一次经验,可能并不适用于目前wind.js。 那次我在使用时出现了一个错误,但是游览器的断点停止在了 eval(Jscex.compile这一行,没有标明出错的原因,并把所需要complie的内容 全部标黄了。 这一次经历对我造成不太好的感觉。不过关于错误报告,目前好象是在console 里面有把编译阶段出现的错误类型和大致内容写出来,这样挺好的。 (断行版)
@jeffz 我真的是非常想去,可是周五要上班,周六半天加班,好不容易周日有空, 周日又是编程马拉松,对我这种菜鸟,就不考虑了。哈哈,提个建议,hujs按天分开 卖票,大多数人都只能去一天,却要支付去3天的钞票,再加路费住宿,还是会让人 稍微肉疼一下的。 最后祝wind.js一番wind顺。
有一个小bug 当我的程序里面有这样一段代码的时候
if (! /^\/.Srv\/./g.test(ph)) {
通过wind编译之后会有这样一段代码
/* if (! /^\/.*Srv\/.*/g.test(ph)) { */
这里,我打不出来※号 简单的说就是,当我的javascript的正则表达是里面 //g这样的正则表达式里面有※/的时候 wind编译出来的代码就会报错
因为那代码里面已经有※号斜杠了,而wind编译之后也用※号斜杠来注释这段代码
var Wind = require("wind");
var mergerJsAsync = eval(Wind.compile("async",function(paths){
$await(Wind.Async.sleep(100));
for(var i=0; i<10; i++) {
(function(i){
console.log(i);
})(i);
}
}));
mergerJsAsync().start();
@jeffz 你测一下,这段代码有bug,编译无法通过,
var Wind = require("wind");
var mergerJsAsync = eval(Wind.compile("async",function(paths){
$await(Wind.Async.sleep(100));
for(var i=0; i<10; i++) {
void function(i){
console.log(i);
}(i);
}
}));
mergerJsAsync().start();
这样就没问题
这个小问题挺重要的,不然初学者脑袋就大了,编译之后少了两个括号 (function(){ … })() 变成 function(){ … }();
错误提示,SyntaxError: Unexpected token (
我是真正在实际项目中遇到的,以后要是遇到一些小bug还得请你多多帮忙 我叫 木木勇 wind总体来说是非常优秀的,确实不错,有机会写个源码分析的文章给我们看看呗 像mootools一样能容易懂源码的,我用着比较放心 jquery我就不敢用了,源码飞来飞去的,完全搞不懂
Wind.Async.Task.toTask = function(arg) {
if(Task.isTask(arg)) return arg;
return Task.create(function(tk){
tk.complete("success",arg);
});
};
Task中增加一个这个方法怎么样? 有这个方法,写起代码来就更方便了
@jeffz 在whenAll的时候,我知道里面的对象可能是Task,也可以能是一个值 或者在$await的时候,我想容错性更高,里面的值我不想判断是否是Task,统一 当做它是Task 这种情况比较多,如果要写一段判断的代码,就比较麻烦了
@jeffz var obj = 2; … N多代码之后(或者别人写的API,我允许别人返回一个真实的值,也允许他返回一个Task),obj可能是Task,也可能是一个值2,3,4什么的 obj = $await(Task.toTask(obj));
var Wind = require("wind");
var Task = Wind.Async.Task;
var testFn = eval(Wind.compile("async",function(){
var obj = {"f0":"aa","f1":"bb"};
for(var i=0; i<10; i++) {
$await(Wind.Async.sleep(100));
if(i === 0) continue;
for(var key in obj) {
if(key === "f0") continue;
console.log(key);
}
}
}));
testFn().start();
这段代码编译之后有bug,里层for循环的continue被误认为是外层的for循环了, 期望打印出来的值是9个bb,但实际上没有打印出来任何值,你试试看
- var Wind = require(“wind”); var testFn = eval(Wind.compile("async",function(){ for(var i=0; i<10; i++) { $await(Wind.Async.sleep(100)); if(i === 0) continue; for(var key in {"f0":"aa","f1":"bb"}) { $await(Wind.Async.sleep(100)); if(key === “f0”) continue; console.log(key); } } })); testFn().start(); 这段代码得出正确的结果.
2.但是,如果我只注释了里层for循环的$await那一句:
var Wind = require("wind");
var testFn = eval(Wind.compile("async",function(){
for(var i=0; i<10; i++) {
$await(Wind.Async.sleep(100));
if(i === 0) continue;
for(var key in {"f0":"aa","f1":"bb"}) {
//$await(Wind.Async.sleep(100));
if(key === "f0") continue;
console.log(key);
}
}
}));
testFn().start();
得出的结果是错误的…
3.如果我注释掉了两条$await语句:
var Wind = require("wind");
var testFn = eval(Wind.compile("async",function(){
for(var i=0; i<10; i++) {
//$await(Wind.Async.sleep(100));
if(i === 0) continue;
for(var key in {"f0":"aa","f1":"bb"}) {
//$await(Wind.Async.sleep(100));
if(key === "f0") continue;
console.log(key);
}
}
}));
testFn().start();
得出的结果也是正确的…
这里,有点诡异,应该是一个bug…
我看到你的源码中sleep是用这个方法setTimeout(fn, delay)来实现的 但是,我的问题是,当delay的值为0的时候,setTimeout(fn, 0)这样是有问题的 最好用这个setImmediate来实现, 至少,你可以在文档上提醒一下用户这个问题
var Wind = require("wind");
var Task = Wind.Async.Task;
var testAsync = eval(Wind.compile("async",function(){
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var bb = $await(aaTk());
console.log(bb);
}));
testAsync().start();
这一段代码,得出了正确的结果,aaa
但是,如果我一个不小心丢了两个括号:
var Wind = require("wind");
var Task = Wind.Async.Task;
var testAsync = eval(Wind.compile("async",function(){
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var bb = $await(aaTk);
console.log(bb);
}));
testAsync().start();
报错信息是: TypeError: Cannot read property ‘error’ of undefined 这中报错信息实在太隐蔽了,你看看有没有办法做的让报错信息准确一点
var Wind = require("wind");
var Task = Wind.Async.Task;
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var testAsync = eval(Wind.compile("async",function(){
var tt = aaTk();
var bb = $await(tt);
console.log(bb);
// var cc = $await(tt);
// console.log(cc);
}));
testAsync().start();
这段代码得出了正确的结果:aaa
var Wind = require("wind");
var Task = Wind.Async.Task;
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var testAsync = eval(Wind.compile("async",function(){
var tt = aaTk();
var bb = $await(tt);
console.log(bb);
var cc = $await(tt);
console.log(cc);
}));
testAsync().start();
这段代码去报错了: An error occurred in "complete listener": TypeError: Cannot read property ‘error’ of undefined 这让我难以理解,能不能给我解释一下为什么这段代码会报错? 谢谢!
再有:
var Wind = require("wind");
var Task = Wind.Async.Task;
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var testAsync = eval(Wind.compile("async",function(){
var tt = aaTk();
//tt.start();
var bb = $await(tt);
console.log(bb);
}));
testAsync().start();
这段代码得出了正确的结果:aaa 但是:
var Wind = require("wind");
var Task = Wind.Async.Task;
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var testAsync = eval(Wind.compile("async",function(){
var tt = aaTk();
tt.start();
var bb = $await(tt);
console.log(bb);
}));
testAsync().start();
这段代码却报错了,报的错是: TypeError: Cannot read property ‘error’ of undefined 这让我非常费解???你看看,是bug还是我哪里理解的不对
var Wind = require("wind");
var Task = Wind.Async.Task;
var aaTk = function(arg) {
return Task.create(function(tk){
tk.complete("success","aaa");
});
};
var testAsync = eval(Wind.compile("async",function(){
var tt = aaTk();
tt.start();
var bb = $await(Task.whenAll(tt));
console.log(bb);
}));
testAsync().start();
这段代码确实正确的,运行通过…
前两天用node写程序时,顺便查了一下 async.js 和 jscex(wind.js)两个的api. 仅就我个人看法.觉得 async.js的api 更友好. windjs感觉稍稍复杂一点.而且有讨厌的eval.
以前也接触过jscex.js, 是真的想支持国产.并使用国产. 所以请问老赵,为何不把eval封装到类库里 而要让开发者自己每次都写呢?
/***********************************************************************
Async helpers
***********************************************************************/
var sleep = Async.sleep = function (delay, /* CancellationToken */ ct) {
return Task.create(function (t) {
if (ct && ct.isCancellationRequested) {
t.complete("failure", new CanceledError());
}
var seed;
var cancelHandler;
if (ct) {
cancelHandler = function () {
clearTimeout(seed);
t.complete("failure", new CanceledError());
}
}
var seed = setTimeout(function () {
if (ct) {
ct.unregister(cancelHandler);
}
t.complete("success");
}, delay);
if (ct) {
ct.register(cancelHandler);
}
});
}
@jeffz 定义了两个seed