簡體   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