2014-04-08 39 views
0

我是nodejs的新手,最近我不確定如何按順序安排任務,以便它們的行爲正確。下面如何推遲解決nodejs中的任務

兩個例子

arr.forEach(function(elem){ 
    //do many many things 
}); 
console.log('done, now take ur pick'); 
stdin.on('input', function action(){ 
    ... 
}) 

我怎麼可以設置stdin.on火arr.forEach後。 和問題2我想如果我做

fn1(); 
fn2(); 

function fn1(){ 
    //long long code 
} 

function fn2(){ 
    console.log('fn2 is done!') 
} 

並運行上述情況,執行將在

線程FN1 FN2 FN1 FN1 FN1,對不對?如何防止這種情況?

+0

*只有在'forEach'循環結束後,您才能*聽'stdin'上的'input'事件。由於你的問題是關於異步行爲的,你需要向我們展示*你實際調用的異步函數。請發佈「許多東西」和「長長碼」的相關部分! – Bergi

回答

3

node.js中的函數是同步的或異步的。同步碼在一個線程中運行,因而表現得完全像你使用的代碼:

fn1(); 
fn2(); 
fn3(fn4()); 

將運行fn1,然後fn2,然後fn4,然後fn3(在fn4結果作爲參數傳遞) 。

異步代碼引發了一些操作,並將其作爲參數執行時執行的函數(這可能會反過來引發另一個異步操作)。你立即得到控制權。例如:

doSomeAsyncThing(function() { 
    console.log("did the async thing"); 
}); 
console.log("hello"); 

執行方式如下:首先,打開異步操作,然後打印「hello」。一段時間後,異步操作完成,因此調用回調,並打印「異步事件」。

如果你想要做一個異步的事情,然後做另一件事異步第一個完成後,以標準的方式是窩的回調:

async1(function() { 
    async2(function() { 
     console.log("async1 and async2 finished"); 
    }); 
}); 

雖然therebetter選項。

所以在第二個例子中,如果fn1是同步的,它將完全按照您所寫的完全一樣。如果fn1必須做一些事情異步,它也必須是異步的,所以你必須把它寫這樣的:

function fn1(callback) { 
    // do some sync stuff 
    doSomethingAsync(function() { 
     // do more sync stuff 
     doSomethingMoreAsync(function() { 
      // do more sync stuff 
      callback(); // call the callback once everything is completed 
     }); 
    }); 
} 

然後調用它像這樣

fn1(function() { 
    fn2(); 
}); 

這可以簡化到:

fn1(fn2); 

在你的第一個例子中,請注意array.forEach是同步的。如果你的// do many many things都是同步的,那麼它就會像你寫的一樣工作,但是如果在那裏有一個異步操作,你可以手動實現一個計數器,或者只使用async庫或Promise iterator utilities

+0

很好的解釋,但async1(fn-> async2(fn))與fn1(fn2)之間有什麼區別?他們是不是以同樣的方式實現回調的相同想法? – user2167582

1

通過將stdin添加到forEach函數的回調函數中。像:

arr.forEach(function(elem){ 
    //do many many things 
}, function() { 
    console.log('done, now take ur pick'); 
    stdin.on('input', function action(){ 
     ... 
    }); 
}); 

使用此,只有在forEach循環完成後纔會調用stdin和console.log函數。

+0

所以一般情況下,如果我想按順序執行兩個函數,總是需要回調?我把fn2傳給fn1? – user2167582

+0

是的。由於非阻塞屬性,函數2將在函數1開始執行後立即執行,並且不會等待函數1完成。 – Ritikesh

+0

我試過了,現在stdin.on永遠不會被觸發,程序結束 – user2167582