2013-11-14 48 views
3

我有一個關於Node中的異步方法API的問題。NodeJS在繼續之前檢查函數完成

所以,我有一個功能,我們稱之爲longSetup(callback)

顧名思義,longSetup(callback)需要很長時間才能完成。但是,這種設置可以與其他事情並行完成。所以,當longSetup()正在發生時,我可以設置其他的東西。

所以一旦longSetup()完成,該類已準備好執行另一個功能,如serveData()

現在,我不知道什麼時候會調用serveData()serveData()基於用戶I/O,可在longSetup()完成之前調用,或可在longSetup()完成之後調用。另外,我從不直接調用serveData()

這是真的,我需要longSetup()之前serveData()可以成功執行完成,但我想利用這一事實,即longSetup()可以異步完成,因此我不想執行的同步版本longSetup();我寧願在那段時間內完成其他設置。

由於serveData()可以隨時調用,我想檢查longSetup()是否在調用serveData()時完成。如果完成,請繼續serveData()。如果不是,則等待longSetup()完成,然後繼續執行。由於longSetup()僅被調用一次,所以在大多數情況下我不會等待。另外,如果用戶I/O需要時間,則longSetup()將在第一次調用serveData()時完成。

我已經通過了幾個關於等待函數返回執行另一個函數/在另一個函數之後執行另一個函數之前返回的問題和答案,我理解了Node的異步方式以及爲什麼要使用回調函數。然而,這是一個不同的用例,我想知道節點是否提供了一些等待另一個異步函數的方式。

謝謝大家!

+0

呼叫serveData()從longSetup(的底部) – dandavis

+1

切換的布爾時'longSetup'完成並與功能的其餘部分之前,前檢查它裏面'serveData'? – thgaskell

+0

你看過承諾嗎? https://github.com/kriskowal/q似乎很受歡迎。 – Diver

回答

1

@ arturgrzesiak的回答是從longSetup呼叫serveData並且無法延遲執行serveData直到longSetup完成。 編輯在更仔細地閱讀他的答案時,看起來我錯了,serveData將在longSetup的末尾被調用一次。但是,如果我的解決方案應該允許serveData被多次調用。多個用戶在安裝期間請求數據。

var setupFinished = false; 

var longSetup = function() { 
    ... 
    // at end: 
    setupFinished = true; 
} 

var serveDataWrapper = function(query){ 
    if(!setupFinished){ 
    setTimeout(
     function(){ 
     serveDataWrapper(query); 
     }, 
     200 //ms 
    ); 
    } else { // setup is finished 
    serveData(query); 
    }; 
} 

var serveData = function (query) { 
    // longSetup is now guranteed to be complete 
}; 

app.get('/', function(req, res){ 
    serveDataWrapper(req.query['query']); 
}); 
+0

我將這個答案標記爲正確的,因爲它確實提供了**解決方案來解決我期望達到的效果。另外,正如大家所指出的那樣,NodeJS本身並沒有提供這種效果。但是,如果您(@Plato)或其他人提出了更新的答案(可能是因爲將來會有新的API),我也會相應地更新答案。再次感謝! – codeBearer

1

我覺得這可能是一個合適的解決方案爲您提供:

var setupInfo = { serveData : false, setupFinished : false } 

var longSetup = function() { 

    ... 

    // at the very bottom 
    if (setupInfo.serveData) { 
     serveData(); 
    } 
    setupInfo.setupFinished = true } 
} 

var serveData = function() { 
    // at the very top 
    if (!setupInfo.setupFinished){ 
     setupInfo.serveData = true; 
     return; 
    } 

    ... 
} 

如果你想serveData你必須保持一個計數器,而不是簡單的bool多次。


不要以爲node.js中您的任務提供了一些API,但也有肯定的外部庫來處理這個問題,這是基於promise patternHere是一個相當古老的,但仍然有用的文章在這個話題上。

+0

感謝您的回覆!但是,我不會調用'serveData()'。 'serveData()'將作爲某個用戶I/O的結果被調用。這就是說,在'serveData()'實現中,我希望等待bool直到它被設置,然後繼續。我可以輪詢bool或者實現我自己的隊列,但是我想知道Node是否已經提供了相同的API。 – codeBearer

+0

已更新代碼以使其具體說明我的意思是函數聲明。何時以及由誰來調用並不重要,但它仍然會提供所需的同步。 –

+0

yup如果你在'longSetup'的完成回調調用之前堅持允許調用'serveData',那麼我知道的唯一解決方案是跟蹤全局作用域變量的狀態,因爲@arturgrzesiak在此回答中建議 – Plato

相關問題