CNode

消除你对Wind.js的疑虑

Jjin52yang发布于14 年前最后回复14 年前20 回复16655 浏览0 收藏

eval is (always) evil

eval大概也算是整个ECMAScript语言中最强大的一个方法, 他就像是一个完整的ECMAScript解析器。你说它evil,我也承认这个 方法会存在危险,有可能带来安全问题,特别是在用它执行用户输入 数据的情况下。但Wind.js是用eval来运行已经“编译”后的代码, 让你更舒服顺畅的来编写异步回调的代码。这些代码是你自己写的, 所以不必担心代码注入、跨站脚本攻击这样的安全问题。没有这这个 困扰和担忧,我相信eval应该是美好的。

API太丑,eval为什么不封装?

通过eval执行的代码是被认为是包含该次调用的执行环境的一部分, 因此被执行的代码具有与该执行环境有着相同的作用域链。

var Wind = require("wind");

var msg = 'hello world';
eval("console.log(msg)");//hello world

var msg = 'hello world';
var newFunc = eval(Wind.compile("async", function () { 
	console.log(msg);
}));
newFunc().start();//hello world

变量msg是在eval外定义的,但eval中还是能够打印"hello world"。 如果包装起来如法访问到msg这个变量。

var Wind = require("wind");

var vm = require("vm");
var sandbox = {
      Wind: Wind,
      console:console
};

function $async(fun){
	var script = vm.createScript(Wind.compile("async", fun));
	return script.runInNewContext(sandbox);
}

var msg = 'hello world';
var newFunc = $async(function () { 
	console.log(msg);
});
newFunc().start();//[WARNING] An unhandled error occurred: ReferenceError: msg is not defined

上面的例子中看到我们使用vm模块对eval有一个简单的包装,可以直接 使用$async方法来替换以前的写法。从打印信息中,你很容易看出访问 不到msg这个参数。麻烦请注意一下调用script.runInNewContext()方法 时传入了一个sandbox对象,这相当于往代码运行环境中添加上下文参数。 如果sanbox这个参数不传递,运行上端代码会报ReferenceError: Wind is not defined的错误。这就是eval为什么无法包装的原因。

如果你的代码不需要依赖上下文你可以用上述方法包装,例如这样:

var Wind = require("wind");

var vm = require("vm");
var sandbox = {
      Wind: Wind,
      console:console
};

function $async(fun){
	var script = vm.createScript(Wind.compile("async", fun));
	return script.runInNewContext(sandbox);
}

var fib = $async(function () {

    $await(Wind.Async.sleep(1000));
    console.log(0);
    
    $await(Wind.Async.sleep(1000));
    console.log(1);

    var a = 0, current = 1;
    while (true) {
        var b = a;
        a = current;
        current = a + b;

        $await(Wind.Async.sleep(1000));
        console.log(current);
    }
});

fib().start();

Wind.js很重很慢不适合前端

Wind.js基础组件及异步运行库共计4K大小(Minified + GZipped), Wind.js完全不会给前端带来负担,给你带来顺畅舒服的异步编程体验。

生成的代码看不懂,难以调试

Wind.js生产的代码也完全是Javascript代码,你无需为调试担忧。 下面是一个例子,我相信你很容易就可以看懂。

// Original: 
function () {

    $await(Wind.Async.sleep(1000));
    console.log(0);
    
    $await(Wind.Async.sleep(1000));
    console.log(1);

    var a = 0, current = 1;
    while (true) {
        var b = a;
        a = current;
        current = a + b;

        $await(Wind.Async.sleep(1000));
        console.log(current);
    }
}

// Windified: 
/* async << function () { */     (function () {
                                     var _builder_$0 = Wind.builders["async"];
                                     return _builder_$0.Start(this,
                                         _builder_$0.Delay(function () {
/*     $await(Wind.Async.sleep(1000)); */    return _builder_$0.Bind(Wind.Async.sleep(1000), function () {
/*     console.log(0); */                        console.log(0);
/*     $await(Wind.Async.sleep(1000)); */        return _builder_$0.Bind(Wind.Async.sleep(1000), function () {
/*     console.log(1); */                            console.log(1);
/*     var a = 0, current = 1; */                    var a = 0, current = 1;
                                                     return _builder_$0.While(function () {
/*     while (true) { */                                 return true;
                                                     },
                                                         _builder_$0.Delay(function () {
/*         var b = a; */                                     var b = a;
/*         a = current; */                                   a = current;
/*         current = a + b; */                               current = a + b;
/*         $await(Wind.Async.sleep(1000)); */                return _builder_$0.Bind(Wind.Async.sleep(1000), function () {
/*         console.log(current); */                              console.log(current);
                                                                 return _builder_$0.Normal();
                                                             });
                                                         })
/*     } */                                          );
                                                 });
                                             });
                                         })
                                     );
/* } */                          })

eval性能方面会有问题

有童鞋提出这方面的问题,但不知道提供什么样子的测试才能令人信服,从而消除疑虑,放心大胆的使用Wind.js。 这个问题还在收集整理中...

写在最后

在ADC被老赵的执着打动了,支持老赵从文档开始吧。 如果你还有对Wind.js的任何疑虑都可以留言,这个文档的目的就是消除你对Wind.js的疑虑。 原帖地址,会不断更新:这里

查看回复

回复 (20)

J
jeffz#7·14 年前
引用 jeffz多谢支持! 在9月份的沪JS大会上我会想谈Jscex是怎么支持调试的,以及一些JavaScript调试方面一些不太被人关注的地方。接下来一段时间Jscex会有一系列增强调试的功能,说Jscex...

@byvoid 首先nodejs不是用来写计算密集型应用的,一个IO就打倒千万次方法调用,其次Jscex从理论上说就不会降低性能……你说说你要什么样的测试吧……

H
hahadekuai#8·14 年前

弱弱的问下,这个与setTimeout(function(){},mil) 的差别有多大。

J
jeffz#9·14 年前
引用 hahadekuai弱弱的问下,这个与setTimeout(function(){},mil) 的差别有多大。

sleep吗?没差别,sleep内部就是封装了setTimeout

V
vincentking#10·14 年前

呵呵,在ADC,吸引最多人的一次演讲确实是老赵的。

J
jeffz#11·14 年前

多谢支持!

在9月份的沪JS大会上我会想谈Jscex是怎么支持调试的,以及一些JavaScript调试方面一些不太被人关注的地方。接下来一段时间Jscex会有一系列增强调试的功能,说Jscex不容易调试的同学不妨关注一下。

J
jin52yang#13·14 年前

担心eval性能方面会有问题的童鞋,可以提出你的担心纠结的情境

D
DoubleSpout#14·14 年前

老赵,你可以试着结合一些常用的异步场景,比如mongodb数据库访问,或者异步文件读写做一些压力测试数据,比较wind.js和原生的异步代码性能差别有多大。

A
atian25#16·14 年前

一直有在关注Wind.js, 不过暂时没有应用到.

有个建议, 觉得官方的示例, 太枯燥了,很容易把初学者吓到. 就一个冒泡排序有点孤单, 可以再做几个类似之前blog上改写nodeclub那样的入门教程.

PS: http://windjs.org/cn/docs/async/samples/browser/sorting-animations/ 底部的链接错了.

D
DoubleSpout#17·14 年前
引用 DoubleSpout老赵,你可以试着结合一些常用的异步场景,比如mongodb数据库访问,或者异步文件读写做一些压力测试数据,比较wind.js和原生的异步代码性能差别有多大。

@jeffz 因为用node.js的大部分都是考虑大并发的情况下,我们公司现在就用node.js做了几个项目都是这样的情况,比如一些对内的api查询接口,wind.js不知道性能损失会有多少,可能我个人比较关注这些吧

J
jeffz#18·14 年前
引用 DoubleSpout老赵,你可以试着结合一些常用的异步场景,比如mongodb数据库访问,或者异步文件读写做一些压力测试数据,比较wind.js和原生的异步代码性能差别有多大。

@snoopy 如果你了解Wind.js就会知道它不会造成性能损失啊,如果不了解你也不会用是不是……所以我一直觉得做性能测试就是个伪命题……

参与回复
登录后即可参与回复。登录