簡體   English   中英

如何使用Node.js Fibers運行代碼

[英]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代碼中發生了什么的任何想法? 並提前感謝...

例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 但是,上面的代碼也會出錯(說明光纖已在運行)。 在分析執行順序時,人們可能很容易理解為什么。

  1. 變量f 設置為光纖。
  2. 運行光纖:
    1. 設置可變fiber指向當前正在運行的纖維。
    2. 調用函數sample
    3. 撥打
    4. 調用 fiber.run ,它會在當前光纖已經運行時給出錯誤。

此代碼的結構是正確的,但它假定sample是一些不立即調用回調的異步函數。 讓我們用這個替換你的sample函數:

function sample(callback) {
    setTimeout(function() {
        callback("this callback");
    }, 500);
}

現在,上面的代碼不會發出錯誤,因為sample立即返回。 光纖內部的執行順序是:

  1. fiber 設置為指向當前正在運行的光纖。
  2. 調用 sample ,它返回而不調用回調(尚未)。
  3. 調用 `Fiber.yield(),它'暫停'當前的光纖。
  4. 500毫秒后, 調用回調。
  5. 調用 fiber.run()傳遞'this callback',它恢復光纖。
  6. Fiber.yield返回, str 設置為'this callback'。
  7. 登錄到控制台的字符串。

觀察到步驟4在光纖執行之外完成。

例2

而在第一個例子中沒有運行光纖(因此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轉換為帶回調的異步函數,然后通過傳染,您還必須將f2f1轉換為異步函數。 使用光纖,您可以將f1f2f3保持為正常功能(無回調)。 你需要在f3一些Fiber.yield()魔法,你還需要從Fiber內部調用f1 ,但你不必擔心f1f2中的回調。

因此,當您在高級函數和它們調用的低級異步函數之間有多層代碼或復雜的控制流時,光纖確實會閃耀。

另外,編寫光纖的Marcel建議您不要在代碼中直接使用Fiber.yield() ,而是使用期貨庫。 Fiber.yield一起使用可以了解纖維是由什么制成的,但我鼓勵您將期貨庫用於實際項目。 它還可以幫助您並行化代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM