2012-06-28 98 views
2

我想知道,如果node.js訂單異步調用啓動/完成作出任何保證。node.js保存異步執行順序嗎?

我不這麼認爲,但是我已經在互聯網上看過一些代碼示例,我認爲這會出現問題,因爲異步調用可能無法按預期順序完成,但這些示例通常在由於其單線程異步模型,節點有多大。然而,我找不到這個普遍問題的直接答案。

這是不同的節點模塊做出不同保證的情況嗎?例如,在https://stackoverflow.com/a/8018371/1072626的答案中明確指出涉及Redis的異步調用保留了訂單。

這個問題的癥結可以到如下執行(或類似)是在節點嚴格安全煮?

var fs = require("fs"); 
fs.unlink("/tmp/test.png"); 
fs.rename("/tmp/image1.png", "/tmp/test.png"); 

據筆者需要調用unlink,因爲重命名將在Windows上,如果有一個預先存在的文件失敗。然而,這兩種調用是異步的,所以我最初的想法是在調用rename應在unlink回調,以保證異步rename操作開始之前,否則可能rename先執行,導致錯誤的I/O完成異步。

+1

取消鏈接將在重命名之前執行,但重命名不保證在取消鏈接完成後執行,除非重命名在取消鏈接的回調中。 –

+1

值得注意的是,Redis是一個特例;它一次只運行一個命令,而Node.js驅動程序是爲了利用這個事實而編寫的。 –

+0

@BrandonTilley謝謝,這說明模塊之間存在差異,並且通常我的理解是正確的。 – vossad01

回答

3

異步操作沒有任何確定的執行時間。

當你調用unlink,它要求OS刪除的文件,但它沒有定義時OS實際上將刪除該文件;它可能是毫秒或一年後。

異步操作的整點是,他們不依賴於對方,除非明確說明如此。

爲了renameunlink後發生,你必須修改你這樣的代碼:

fs.unlink("/tmp/test.png", function (err) { 
    if (err) { 
     console.log("An error occured"); 
    } else { 
     fs.rename("/tmp/image1.png", "/tmp/test.png", function (err) { 
      if (err) { 
       console.log("An error occured"); 
      } else { 
       console.log("Done renaming"); 
      } 
     }); 
    } 
}); 

,或者使用的FS功能同步版本(注意,這些將阻止執行的線程) :

fs.unlinkSync("/tmp/test.png"); 
fs.renameSync("/tmp/image1.png", "/tmp/test.png"); 

也有資料庫,如async,使異步代碼更好看:

async.waterfall([ 
    fs.unlink.bind(null, "/tmp/test.png"); 
    fs.rename.bind(null, "/tmp/image1.png", "/tmp/test.png"); 
], function (err) { 
    if (err) { 
     console.log("An error occured"); 
    } else { 
     console.log("done renaming"); 
    } 
}); 

請注意,在所有示例中,錯誤處理都非常簡單以表示該想法。

1

如果你看的Node.js的documentation你會發現功能fs.unlink需要一個回調作爲參數爲:

fs.unlink(path, [callback]); 

一個動作,你打算採取目前的功能時,返回值應作爲回調參數傳遞給函數。所以,通常在你的情況的代碼將採取以下形式:

var fs = require("fs"); 
fs.unlink("/tmp/test.png", function(){ 
    fs.rename("/tmp/image1.png", "/tmp/test.png"); 
}); 

在取消鏈接的特定情況下,並重新命名也有在Node.js的同步功能,可作爲fs.unlinkSync(路徑)和FS .renameSync(oldPath,newPath)。這將確保代碼同步運行。

此外,如果你想使用異步執行,但保留更好的可讀性,你可以考慮像async庫。它也有一個類似的實現並聯,串聯,瀑布等

希望這有助於不同的模式選擇。

+1

這是一個奇怪的巧合,我們都在這裏同時:) :) – penartur

+0

@penartur似乎如此... :) – almypal