簡體   English   中英

node.js並行執行

[英]node.js parallel execution

我正在嘗試在node.js中學習並行執行。 我在下面寫了示例代碼。 但是,輸出是串行的。 首先打印0..99然后打印100..200。

我理解這是因為node.js本質上是單線程的並且在循環內部,線程被for循環捕獲。

我想要了解的是在什么情況下這個flow.parallel結構是有用的? 對I / O或數據庫的任何請求都將在node.js中異步。 那為什么我們需要flow.parallel

var flow = require('nimble');


flow.parallel([

    function a(callback)
    {
        for(var i=0;i<100;++i)
        {
            console.log(i);

        }
            callback();
    },
    function b(callback)
    {

        for (var i=100;i<200;++i)
        {
            console.log(i);

        }
        callback();
    }
    ]);

在大多數情況下使用像這樣的並行流,你不會在for循環中打印一堆數字(這恰好阻止了執行)。 當您注冊功能,它們登記在其中你,你的數組傳遞給在定義它們的相同順序parallel 在上面的例子中, function a第一個, function b第二個。 因此,Node的事件循環將在稍后的未公開時間調用a()然后調用b() 因為我們知道那些for循環是阻塞的,並且節點在單個線程中運行,所以它必須在a()內完成整個for循環,最后在Node的事件循環再次控制它之前返回,其中b()是在隊列中等待進程是類似的。

為什么並行流控制結構有用? 按照設計,您不應該在節點內執行阻塞操作(請參閱您的示例)。 a()使用整個線程,然后b()將在其他任何事情發生之前使用整個線程。

a()  b()
 |
 |
 |
 |
RET
     |
     |
     |
     |
    RET

現在,假設您正在制作一個用戶可以注冊的Web應用程序,同時上傳圖片。 您的用戶注冊可能包含以下代碼:

var newUser = {
  username: 'bob',
  password: '...', 
  email: 'bob@example.com',
  picture: '20140806-210743.jpg'
}

var file = path.join(img.IMG_STORE_DIR, newUser.picture);

flow.parallel([
  function processImage(callback) {
    img.process(function (err) {
      if (err) return callback(err); 

      img.save(file, function (err) {
        return callback(err); // err should be falsey if everything was good
      })
    });
  },
  function dbInsert(callback) {
    db.doQuery('insert', newUser, function (err, id) {
      return callback(err);
    });
  }
], function () {
  // send the results to the user now to let them know they are all registered! 
});

這里的內部函數是非阻塞的,並且都調用處理或網絡負載操作。 然而,它們相互獨立。 你不需要一個完成另一個開始。 在我們無法看到代碼的函數中,它們使用帶有函數回調的更多異步調用,每個調用都會為Node處理另一個項目。 節點將嘗試清除隊列,在CPU周期之間均勻分配工作負載。

我們希望現在發生這樣的事情:

a = processImage
b = dbInsert
a()  b()
 |
      |
 |
      |
 |   
      |
 |
RET   |
     RET

如果我們將它們串聯起來,即你必須等待在db插入之前完全處理圖像,你必須做很多等待。 如果系統上的IO非常高,那么節點將在操作系統上等待它的拇指。 相比之下,理論上使用並行將允許慢速操作產生更快的操作。

如果Node自己做到這一點,為什么我們真的需要它呢? 關鍵是在你省略的第二個參數中。

nimble.parallel([a,b], function () {
  // both functions have now returned and called-back. 
}); 

您現在可以看到兩個任務何時完成,默認情況下節點不會執行此操作,因此它可能是一個非常有用的東西。

flow.parallel為您提供可重用的邏輯,用於確定所有並行操作何時完成。 是的,如果你剛剛做了db.query('one');db.query('two');db.query('three'); ,它們都會根據異步的性質並行執行,但是您必須編寫一些樣板代碼來跟蹤它們何時完成以及是否遇到錯誤。 這是flow.parallel (或任何流控制庫中的對應物)提供的那部分。

Node.js中的並行執行

使用Nodejs讀取parellel執行中的文件目錄

創建目錄

mkdir演示

創建文件

demo.txt,demo2.txt,demo3.txt

每個文件都有一些包含或段落

創建文件word_count.js

 var fs = require('fs'); var completedTasks = 0; var tasks = []; var wordCounts = {}; var filesDir = './test'; function checkIfComplete() { completedTasks++; if(completedTasks == tasks.length){ for (var index in wordCounts){ console.log(index +': ' + wordCounts[index]); } } } function countWordsInText(text) { var words = text .toString() .toLowerCase() .split(/\\W+/) .sort(); for (var index in words) { var word = words[index]; if(word) { wordCounts[word] = (wordCounts[word]) ? wordCounts[word] + 1 : 1; } } } fs.readdir(filesDir, function(err, files){ if(err) throw err; for (var index in files) { var task =(function (file) { return function() { fs.readFile(file, function(err, text) { if(err) throw err; countsInText(text); checkIfComplete(); }); } })(filesDir + '/' + files[index]); tasks.push(task); } for (var task in tasks) { tasks[task] (); } }); 

暫無
暫無

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

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