繁体   English   中英

Node.js中的Promise.all不会阻止使用map和async调用的函数调用

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM