2012-07-21 85 views
4

我似乎無法掌握如何使用NodeJs來維護異步控制流。在我看來,所有的嵌套使得代碼很難閱讀。我是新手,所以我可能錯過了大局。Nodejs異步混淆

什麼是錯的只是編碼這樣的事情...

function first() { 
    var object = { 
     aProperty: 'stuff', 
     anArray: ['html', 'html']; 
    }; 
    second(object); 
} 

function second(object) { 
    for (var i = 0; i < object.anArray.length; i++) { 
     third(object.anArray[i]); 
    }; 
} 

function third(html) { 
    // Parse html 
} 
first(); 

回答

7

的「大局」是,任何I/O是非阻塞的,並在你的JavaScript異步執行;因此,如果您執行任何數據庫查找,從套接字(例如HTTP服務器)中讀取數據,讀取或寫入文件到磁盤等,則已使用來使用異步代碼。這是必要的,因爲事件循環是單個線程,並且如果I/O不是非阻塞的,程序會在執行時暫停。

可以構造你的代碼,使嵌套更少;例如:

var fs = require('fs'); 
var mysql = require('some_mysql_library'); 

fs.readFile('/my/file.txt', 'utf8', processFile); 

function processFile(err, data) { 
    mysql.query("INSERT INTO tbl SET txt = '" + data + "'", doneWithSql); 
} 

function doneWithSql(err, results) { 
    if(err) { 
    console.log("There was a problem with your query"); 
    } else { 
    console.log("The query was successful."); 
    } 
} 

也有流量控制庫,例如async(我個人的選擇),以幫助避免大量嵌套的回調。

您可能也有興趣this screencast I created on the subject

+0

謝謝。我知道我需要使用異步代碼,我只是無法弄清楚我寫的代碼是否是異步代碼。 – mnort9 2012-07-21 17:29:39

+0

在上面的例子中,如果我在函數'one'中進行了數據庫查找並將數據設置爲'object'的屬性,那麼只有當'object'被完全定義時纔會調用'second'。 – mnort9 2012-07-21 17:31:46

+0

任何執行異步I/O的函數都會執行回調,當I/O完成處理時將調用該回調。 – 2012-07-21 17:32:39

1

As @BrandonTilley說,I/O是異步的,所以你需要回調Node.js來處理它們。這就是爲什麼Node.js只需要一個線程就可以做到這一點(它在單線程中實際上並沒有做更多的事情,而是讓線程等待數據,它只是開始處理下一個任務,而當I/O回來了,然後它會用你給它的回調函數跳回到那個任務)。

但是,嵌套的回調可以採取像一個很好的圖書館,如古老的async或我的新小圖書館:queue-flow。他們處理回調問題,並讓您的代碼保持非嵌套狀態,並且看起來與阻塞同步代碼非常相似。 :)