我有一个关于 Nodejs Fibers 的问题(这对我来说是绝对新的)...我有这个 Nodejs Fibers 的教程,http://bjouhier.wordpress.com/2012/03/11/fibers-and-threads-in-node-js-what-for/,这里有一个例子说
var fiber = Fiber.current;
db.connect(function(err, conn) {
if (err) return fiber.throwInto(err);
fiber.run(conn);
});
// Next line will yield until fiber.throwInto
// or fiber.run are called
var c = Fiber.yield();
// If fiber.throwInto was called we don't reach this point
// because the previous line throws.
// So we only get here if fiber.run was called and then
// c receives the conn value.
doSomething(c);
// Problem solved!
现在基于这个例子,我创建了我自己的代码版本,
var Fiber = require('fibers');
function sample(callback){
callback("this callback");
}
var fiber = Fiber.current;
sample(function(string){
fiber.run(string);
});
var string = Fiber.yield();
console.log(string);
但这给了我一个错误,
/home/ubuntu/Tasks/ServerFilteringV1/test.js:28
fiber.run(string);
^
TypeError: Cannot call method 'run' of undefined
我还有另一种情况,它将在 1000 毫秒后运行一个函数,其中包含回调(我已经这样做是为了在回调之前测试长时间执行的函数),
var Fiber = require('fibers');
function forEach(callback){
setTimeout(function(){
callback("this callback");
},1000);
}
var fiber = Fiber.current;
forEach(function(string){
fiber.run(string);
});
var string = Fiber.yield();
console.log(string);
这 code 在这里给我另一个错误,
/home/ubuntu/Tasks/ServerFilteringV1/test.js:30
var string = Fiber.yield();
^
Error: yield() called with no fiber running
那么,yield () 应该在 run () 函数执行后等待吗?任何关于我的 nodejs 代码中发生的事情的想并提前感谢...
示例1
纤程是一种轻量级的执行线程。像真正的线程和进程一样,纤程必须被赋予一个代码块,以便在运行时执行。从bjouhier获取的代码无常工作。它打算在光纤中运行,如下所示:
var f = Fiber(function() {
var fiber = Fiber.current;
sample(function(str) {
fiber.run(string);
});
var str = Fiber.yield();
console.log(str);
});
f.run();
在光纤上调用run
会运行光纤代码,该代码是作为Fiber
的回调给出的。但是,上面的代码也会给出一个错误(说明光纤已经在运行)。在分析执行顺序时,人们可能会很容易地看到原因。
将变量f
设置为光纤。
运行光纤:
设置变量fiber
指向当前运行的光纤。
sample
.
调用回调。
调用fiber.run
,这将给出错误,因为当前光纤已经在运行。
这个代码的结构是正确的,但它假设sample
是一些异步函数,不会立即调用回调。
function sample(callback) {
setTimeout(function() {
callback("this callback");
}, 500);
}
现在,上面的代码不会发出错误,因为sample
立即返回。
设置fiber
指向当前运行的光纤。
调用sample
,它在不调用回调(还)的情况下返回。
调用'Fiber.yield (),它将暂停当前光纤。
500 毫秒后,调用回调。
调用fiber.run()
通过“此回调”,该回调恢复光纤。
Fiber.yield
返回,将str 设置为“此回调”。
日志字符串到控制台。
观察到步骤 4 是在光纤的执行之外完成的。
示例2
而在第一个例子中,没有运行的光纤(因此fiber
是未定义),在第二个例子中,错误是出于同样的原因抛出的。
产量和运行的函数
放弃控制的意思是“yieldingcontrol”,在本例中是Fiber.yield()
。
为了继续执行 (直接在光纤产生的点之后),必须在光纤上调用run()
。
将值传入和传出光纤的机制是通过产量和运行的相互作用:
由yield
(在光纤内部)返回给run
(在光纤外部)的参数。
由run
(光纤外部)返回给yield
(光纤内部)的参数。
例如,请查看the github repository of node-fibers上的增量生成器。此外,请观察我们的示例 1,给sample
的回调基本上在光纤外部运行,因为它在下一个滴答上运行(即setTimeout
的异步性质)。
正如 Andrew 所解释的那样,正如我的博客文章中所暗示的那样(参见的句子),您必须创建一个Fiber
并使用run()
运行它才能调用Fiber.yield
。
纤维的好处并不明显,当你有一个单一的 async 调用来运行,但考虑到你有一个函数可以调用f2
2调用一个带有回调的低级 async 函数,如果你不使用纤维,你必须把2
因此,当您的高级函数和它们调用的低级异步函数之间有多层代码或复杂的控制流时,光纤真的会发光。
此外,编写光纤的 Marcel 建议您不要直接在代码中使用Fiber.yield()
,而是使用他的futures库。使用Fiber.yield
了解光纤的组成很有趣,但我建议您将futures库用于实际项目。它还将帮助您并行化代码。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(84条)