javascript最大的一个特点就是单线程,但是可以同时挂起多个执行链,同时javascript能够很简单的实现回调函数,这些都十分满足异步编程的要求,这些特点最终也成为了node.js的十分重要的属性,这十分符合非阻塞编程的模型的要求,从而也使得node.js具备了十分优秀的处理并发的能力。。。即使不用c语言,不用涉及epoll等也可以实现很好的并发性能。(当然在内存和cpu等方面还是具有很大的劣势)只需要编写较少的代码,降低了入门的门槛,而且代码越少出bug的可能性也就越小。。。
这里需要说的是,各种异步,函数回调是node.js高性能的基础,但同时也限制了node.js的适用范围,而且也很容易掉到坑中去。。。。例如,在一个大循环中不断的挂起回调作用链,会很容易让node.js爆栈。。而且有的时候很多业务逻辑如果用回调来实现的话,也会给代码的实现带来很大的难度。。。。
这个时候就可以选用fibers模块了,首先来看它的一个典型使用吧:
function doIt(key, value) {
var fiber = Fiber.current;
client.set(key, value, function(err, reply){
fiber.run();
});
Fiber.yield();
}
function doIt2(key) {
var fiber = Fiber.current;
client.send_command("PEXPIRE", [key, 1000 * 60 * 60], function(err, reply){
console.log(err);
console.log(reply);
fiber.run();
});
Fiber.yield();
}
var fn = Fiber(function(str) {
//console.log('wait... ' + new Date);
//console.log(i);
var i = 0;
for (i = 0; i < 1000000; i++) {
var key = "afdsdfdsdsdsffdsfdsfdsdsfadsfdsfdsafdsadsfsfsfafasdfafdsfdsafdsfasafdsfffsdfaddsfdsaasaa" + i;
var value = "ccfdsfadfsafdsfadfafsafdsfdsfdsfafdsfasdfsasfdsfafdsfafdsafsadfasdfafdsfdafsfac";
doIt(key, value);
doIt2(key);
}
console.log('ok... ' + new Date);
});
这里首先用Fiber函数来建立一个需要在同步作用域中执行的函数,接着在需要异步执行的地方,首先var fiber = Fiber.current;用于获取当前的执行域,然后挂起回调,接着是:Fiber.yield();,这句话的作用可以理解为阻塞当前的执行域,并释放cpu,这样就为刚刚挂起的回调提供了cpu了,当回调执行完后fiber.run();用于使yield返回。。。
这样也就实现了将一步转换为同步。。。
其实网上一直有关于node.js的各种评价,其中很多都批评node.js的异步模型限制了它在企业级应用中的使用。。。
其实我倒是觉得这些都无所谓,只要能够利用node.js的优势就好了。。。。