[英]How to run code using Node.js Fibers
我有一個關於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);
這里的代碼給了我另一個錯誤,
/home/ubuntu/Tasks/ServerFilteringV1/test.js:30
var string = Fiber.yield();
^
Error: yield() called with no fiber running
那么,執行run()函數后yield()是否應該等待? 關於我的nodejs代碼中發生了什么的任何想法? 並提前感謝...
光纖是一種輕量級的執行線程。 與真正的線程和進程一樣,必須為光纖提供一段代碼才能在運行時執行。 從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
是一些不立即調用回調的異步函數。 讓我們用這個替換你的sample
函數:
function sample(callback) {
setTimeout(function() {
callback("this callback");
}, 500);
}
現在,上面的代碼不會發出錯誤,因為sample
立即返回。 光纖內部的執行順序是:
fiber
設置為指向當前正在運行的光纖。 sample
,它返回而不調用回調(尚未)。 fiber.run()
傳遞'this callback',它恢復光纖。 Fiber.yield
返回, 將 str 設置為'this callback'。 觀察到步驟4在光纖執行之外完成。
而在第一個例子中沒有運行光纖(因此fiber
未定義 ),在第二個例子中,出於同樣的原因拋出了錯誤。 同樣,代碼需要在光纖內部運行。
光纖必須協同控制另一根光纖(或主要執行線)。 將其與線程和進程的搶先性質進行比較。 放棄控制是' 屈服控制'的意思,在這種情況下由Fiber.yield()
。
要繼續執行(直接在光纖產生的位置之后),必須在光纖上調用run()
。
將值傳入和傳出光纖的機制是通過yield和run的相互作用:
run
的參數(在光纖之外)由yield
(光纖內部)返回。 yield
(光纖內部)的參數由run
(光纖外)返回。 例如,查看node-fiber的github存儲庫上的增量生成器。 另外,觀察我們的示例1,給予sample
的回調基本上是在光纖之外運行,因為它在下一個tick(即setTimeout
的異步性質)上運行。
正如安德魯所解釋的那樣,並且在我的博客文章中暗示(參見示例后面的句子),您必須創建一個Fiber
並使用run()
運行它以便能夠調用Fiber.yield
。
當你有一個異步調用來運行時,光纖的好處並不明顯,但考慮一下你有一個函數f1
調用調用f3
f2
。 如果f3
使用回調調用低級別異步函數,並且如果不使用光纖,則必須將f3
轉換為帶回調的異步函數,然后通過傳染,您還必須將f2
和f1
轉換為異步函數。 使用光纖,您可以將f1
, f2
和f3
保持為正常功能(無回調)。 你需要在f3
一些Fiber.yield()
魔法,你還需要從Fiber
內部調用f1
,但你不必擔心f1
和f2
中的回調。
因此,當您在高級函數和它們調用的低級異步函數之間有多層代碼或復雜的控制流時,光纖確實會閃耀。
另外,編寫光纖的Marcel建議您不要在代碼中直接使用Fiber.yield()
,而是使用期貨庫。 與Fiber.yield
一起使用可以了解纖維是由什么制成的,但我鼓勵您將期貨庫用於實際項目。 它還可以幫助您並行化代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.