【问题标题】:How do I wait for all Promises to finish before executuing ABCD function in Javascript?在 Javascript 中执行 ABCD 函数之前,如何等待所有 Promise 完成?
【发布时间】:2019-02-07 22:39:27
【问题描述】:

每次我向 Google API 请求距离时,我都会创建一个新的 Promise。我希望所有的 Promise 都解决,然后调用 ABCD 函数?现在它立即调用 ABCD 函数。

async function RunBookings(Records) {
  for (var k = 0; k < gDestinationsArray.length; k++) {
    console.log('k' + k);
    let promise = new Promise(function(resolve, reject) {
      console.log('new Promise');
      var DistanceService = new google.maps.DistanceMatrixService();
      DistanceService.getDistanceMatrix({
        origins: gOriginsArray[k],
        destinations: gDestinationsArray[k],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
      }, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          console.log(response);
          var results = response.rows[0].elements; //console.log(results );
          for (var l = 0; l < results.length; l++) {
            gDistanceArray.push(results[l].distance.text);
          }
          setTimeout(function() {
            resolve('Good promise');
          }, 10000);
        } else if (status === google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
          console.log('OVER_QUERY_LIMIT');
          console.log(response);
          console.log(status);
          reject(Error("Bad promise"));
        } else {
          console.log('BAD');
          console.log(response);
          console.log(status);
          reject(new Error("Bad promise"));
        }
      });
    });
    let result = await promise;
  }
}

function ABCD() {

}

RunBookings(Records);
ABCD();

【问题讨论】:

  • RunBookings(Records).finally(ABCD) 可以。
  • 似乎你没有从函数的for循环中返回promise本身的响应。除非我错过了什么。当您调用 runbooking 时,它只会处理信息。没有返回任何内容
  • @divyanshch async functions 总是隐式返回一个承诺。
  • 这是有道理的,即使在这种情况下,虽然没有返回任何值,所以你只会得到一个返回的 void 承诺
  • 没错,但它仍然可以作为处理完成的指示。

标签: javascript asynchronous promise async-await


【解决方案1】:

你应该用 Promise.all(promises)

等待所有的承诺
function RunBookings(Records) {
  const promises = [];

  for (var k = 0; k < gDestinationsArray.length; k++) {
    let promise = new Promise(function(resolve, reject) {

    ..... your code....

    promises.push(promise);
  }

  return promises;
}

function ABCD() {
}


Promise.all(RunBookings(Records))
   .then( val => {
       ABCD();
   });

或使用异步/等待

async function RunBookings(Records) {
  const promises = [];

  for (var k = 0; k < gDestinationsArray.length; k++) {
    let promise = new Promise(function(resolve, reject) {

    ..... your code....

    promises.push(promise);
  }

  return promises;
}

function ABCD() {
}


let result = await RunBookings(Records);
ABCD();

或者如果你想返回一个承诺

async function RunBookings(Records) {
  await Promise.all(gDestinationArray.map(async (gDestination) => {
           ............
  }));
}

RunBookings(Records);
ABCD();

【讨论】:

  • 如果你要这样重写它,RunBookings(Records) 应该返回Promise.all(gDestinationsArray.map((destination, k) =&gt; new Promise((resolve, reject) =&gt; { ... })))
  • Promise.all(promises) 等待数组promises上所有promise的结束,你可以执行ABCD()。 RunBookings(Records) 只能返回一系列与我的解决方案一起使用的承诺。
  • 异步函数返回聚合承诺而不是承诺数组更为规范。消费代码不应该负责从数组构造聚合承诺就是我的意思。
  • 是的,我刚刚在我的 IDE 中尝试了类似于您的第一个回复的内容,并且它有效。不要忘记将 await 放在 Promise.all 之前。
  • 你的最后一个函数是错误的。不要使用await,使用return,您仍然必须使用await RunBookings(Recods); 或使用Bergi 的解决方案。
【解决方案2】:

RunBookings 是一个async function,因此返回一个承诺(它不会阻塞!),因此使用

RunBookings(Records).then(ABCD);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 2015-03-01
    • 1970-01-01
    相关资源
    最近更新 更多