[英]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.