2016-02-27 79 views
1

我仍然不理解異步代碼是如何工作的或者是在NodeJS中創建的。請參閱下面的代碼和輸出。仍然不瞭解NodeJs異步函數

代碼:

var async = require('simple-asyncify'); 


function calc(){ 
    n1 = Math.round(Math.random() * (100 - 1) + 1); 
    n2 = Math.round(Math.random() * (100 - 1) + 1); 
    n3 = n1*n2; 
    // console.log(n3); 
    return n3; 
} 


function longRun(id) 
{ 
    console.log("start long run: "+ id); 

    for(i=0; i<100000000; i++){ 
     calc(); 
    } 

    console.log("end long run: " + id); 
}  

longRunAsync = async(longRun); 


console.log("before"); 
longRunAsync(1, function(){}); 
longRunAsync(2, function(){}); 
longRunAsync(3, function(){}); 
console.log("after"); 

輸出:

before 
after 
start long run: 1 
end long run: 1 
start long run: 2 
end long run: 2 
start long run: 3 
end long run: 3 

沒有線

longRunAsync = async(longRun); 

而使用原始的功能龍潤VS longRunSync輸出爲:

before 
start long run: 1 
end long run: 1 
start long run: 2 
end long run: 2 
start long run: 3 
end long run: 3 
after 

因此,顯然有些東西是異步運行的,但不是我所期望的。它看起來像所有的同步代碼然後迴轉並執行應該以同步方式異步的功能。

爲什麼輸出不喜歡下面,我怎樣才能使它執行這樣的:

before 
start long run: 1 
start long run: 2 
start long run: 3 
after 
end long run: 1 
end long run: 2 
end long run: 3 

我覺得你的想法,我想longRunAsync的每次調用運行良好,異步。

+0

我不知道那個圖書館,但如果你開始了,我會建議你直接承諾 - 例如, https://開頭github上。com/petkaantonov/bluebird –

+1

你的longRun函數是同步的,這就是爲什麼它完成它的工作,然後調用第二個longRun。 – Edgar

+0

我建議你先閱讀[doc for simple-asyncify](https://github.com/lydell/simple-asyncify),然後提出一個更具體的問題,說明你爲什麼會看到某些特定的行爲。簡單異化中沒有魔力。它不會以某種方式在後臺運行同步操作。它只是推遲運行它,直到當前事件循環操作結束。而且,您必須將回調傳遞給您的異步函數,以便了解何時完成或得到結果。請閱讀asyncify文件,如果你真的打算使用它。 – jfriend00

回答

1

你真的沒有正確使用那個'simple-asyncify'庫。您應該處理您的包裝函數返回的回調...

longRunAsync(1, function(){}); 

以獲得您想要的assync行爲。

我想這肯定是某種學習練習,因爲非包裝版本的功能給你非常合理的行爲。爲了得到你想要的輸出,你會重寫你的longRunAsync功能是這樣的(你需要返回ID):

function longRun(id) 
{ 
    console.log("start long run: "+ id); 

    for(i=0; i<100000000; i++){ 
     calc(); 
    } 

    return id 
} 

,並將其放置在回調從包裝的函數:

console.log("before"); 
longRunAsync(1, function(err, id){ 
    console.log("end long run: " + id);}); 
longRunAsync(2, function(){ 
    console.log("end long run: " + id)}); 
longRunAsync(3, function(){ 
    console.log("end long run: " + id)\}); 
console.log("after"); 

這可能會給你想要的東西,儘管它有點不確定。那些longRunAsync不保證以任何特定順序完成。也有可能是這些中的任何一個可能之前

console.log("after"); 

完整,所以您的輸出可能是這個樣子:如果你想YOUT異步功能在某種順序執行

before 
start long run: 1 
start long run: 2 
start long run: 3 
end long run: 1 
after 
end long run: 2 
end long run: 3 

,你必須將它們嵌套(又名回撥地獄)或使用類似https://github.com/caolan/async的東西。

下面是嵌套的外觀(未測試)。但我無法弄清楚如何讓console.log('after')打印出你想要的地方。

console.log("before"); 
longRunAsync(1, function(err, id){ 
    console.log("end long run: " + id); 
    longRunAsync(2, function(){ 
      console.log("end long run: " + id); 
      longRunAsync(3, function(){ 
        console.log("end long run: " + id)\});});});