2017-04-07 117 views
0

我在我的節點代碼中需要從數據庫(MySQL)中檢索4或5個項目的一個點,然後對結果進行一些數學計算,然後將結果返回到調用函數的代碼的主要部分。在我從這些函數或函數中返回數據之前,我無法在代碼中繼續前進。包含嵌套非阻塞函數的節點阻塞函數?

我讀的所有內容都說不創建同步功能,因爲您拿走了使用Node的所有喜悅和美感。但是,我從字面上不能繼續執行我的代碼而沒有函數的結果。

那麼,我不需要這裏的同步功能嗎?如果是這樣,爲什麼感覺這麼錯呢?大聲笑。

我想到做一個大的外部函數是同步的,它包含了4或5個函數,它們實際上完成了這項工作。我可以使嵌套函數異步並使外部函數(容器)同步。

對此有何看法?新的節點,只是第一次嘗試做到這一點。

+2

你不能那樣做。相反,你應該使用承諾。 – SLaks

+0

在繼續執行之前,node.js字面上無法等待異步操作完成。如果你的函數中有嵌入式異步操作,那麼現在整個函數都是異步的。您無法返回該值。請參閱[我如何從異步調用返回響應](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call)討論你的選擇。承諾或回調將被採用。 – jfriend00

回答

1

等待多個I/O操作在繼續之前完成是一個常見問題,特別是對於節點+數據庫。我嘗試儘可能多地執行異步操作,並且只在程序的邏輯流程完全需要它時才阻止。 「使嵌套函數異步」的想法看起來很好。您可以利用Promise.all來啓動所有的異步內容。如果您等待承諾的結果,它將不會轉到下一行代碼,直到Promise.all完成爲止

下面是一些帶有愚蠢但描述性的函數名稱的代碼,我希望這些代碼有用。

async function processIAmTryingToDoAsAsynchAsPossible(allCommandsToExecute) { 
    try { 
    // go get all the data asynchronously and destructure the results. But only move to the next line 
    // once all the async calls have returned 
    const [firstResult, secondResult, thirdResult] = await Promise.all(allCommandsToExecute.map(eachCommandToExecute => executeSqlFunction(eachCommandToExecute))); 

    // assuming it is just math, this is not an i/o operation so it will execute "synchronously" 
    const finalMathProduct = doMathOnThisStuff(firstResult, secondResult, thirdResult); 

    // assuming this is an i/o operation and the final function returns something you need 
    return await functionWeCallAfterGettingTheData(finalMathProduct); 
    } catch (err) { 
    // You'll get here if the Promise.all has a reject, if the final function errors out, 
    // or if you throw an error in one of the other functions. 
    throw err; 
    } 
}