[英]Promise.all in Node.js not blocking in function call using map and async calls
我編寫了一個小模塊,與Zookeeper交談以獲得服務端點列表。 除了返回端點列表的那一部分之外,其他所有東西都工作正常。 在該模塊中,我公開了一個函數,該函數應該返回通過調用getData(來自模塊node-zookeeper-client)而獲得的端點數組,其次數與Zookeeper上特定路徑中的子代次數相同。 我試圖結合數組映射和Promise.all來調用getData x次,但是我的函數在Promise.all解析之前返回,在調用者端以“未定義”變量結尾。 這是我的代碼段:
zookeeper.js
...
const getData = (entry) => {
return new Promise(function(resolve, reject) {
client.getData(
"/application/agent/" + entry,
function (error, data, stat) {
if (error) {
console.log(error);
reject(error);
} else {
console.log('getData resolve %s',data.toString('utf8'));
resolve(data.toString('utf8'));
}
});
});
};
...
function agentsEndpoint() {
console.log('Begin agentsEndpoint...');
var requests = agentList.map(getData);
console.log('requests: %s', requests);
var results = Promise.all(requests);
console.log('results: %s', results);
results.then((endpoints) => {
return endpoints;
});
console.log('...agentsEndpoint return.');
}
module.exports = { agentsEndpoint };
main.js
...
const zk = require('./zookeeper.js');
zk.client.connect();
setInterval(listEndpoints,5000, zk);
function listEndpoints(zk) {
console.log('Calling agentsEndpoint: %s',zk.agentsEndpoint());
}
...
這是控制台輸出:
Begin agentsEndpoint...
requests: [object Promise],[object Promise]
results: [object Promise]
...agentsEndpoint return.
Calling agentsEndpoint: undefined
getData resolve 10.0.0.8/getEndpoint
getData resolve 10.0.0.10/getEndpoint
我的預期行為是該函數應該在結果行等待.then((endpoints)=> {以解決最終的Promise,但是正如您在控制台輸出中看到的那樣,它要解決的時間要晚得多。
我在這里想念的是什么?!?!
您遇到的問題的核心是agentsEndpoint
正在執行異步操作,但未返回任何內容。 為了知道函數的異步部分何時完成,您還需要從此函數返回一個promise,就像getData
一樣。 然后,呼叫者將收到承諾,並在解決時可以使用它。 沒有console.logs
的基本思想將如下所示:
在zookeeper.js中==>
const agentsEndpoint = () => Promise.all(agentList.map(getData));
在main.js ==>
function listEndpoints(zk) {
zk.agentsEndpoint()
.then(elements => console.log('Calling agentsEndpoint: %s', elements))
}
console.log('Calling agentsEndpoint: %s',zk.agentsEndpoint());
您的功能不返回任何東西。
function agentsEndpoint() {
...
console.log('...agentsEndpoint return.');
}
因此, Calling agentsEndpoint: undefined
是有效答案。
您應該將agentsEndpoint
與async一起使用。
您可以使用回調,promise或異步/等待。
參見示例:
function agentsEndpoint() {
console.log('Begin agentsEndpoint...');
var requests = agentList.map(getData);
console.log('requests: %s', requests);
var results = Promise.all(requests);
console.log('results: %s', results);
return results;
}
function listEndpoints(zk) {
zk.agentsEndpoint().then(endpoints => console.log('Calling agentsEndpoint: %s', endpoints);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.