简体   繁体   English

使用 promise.all 结合两个承诺

[英]Combining two promises using promise.all

I have two promises from two different API calls in my VUE JS app, I was thinking maybe both could be combined using a promise.all() approach?在我的 VUE JS 应用程序中,我有来自两个不同 API 调用的两个承诺,我在想也许两者都可以使用promise.all()方法结合起来? If so how could I do this?如果是这样,我该怎么做?

API.js API.js

async function getForecast(lat, lon) {
  try {
    const response = await fetch(`${WEATHER_API_URL}&lat=${lat}&lon=${lon}`);
    return await response.json();
  } catch (error) {
    console.log(error);
  }
}

async function getAddress(lat, lon) {
  try {
    const response = await fetch(`${ADDRESS_API_URL}&lat=${lat}&lon=${lon}`);
    return await response.json();
  } catch (error) {
    console.log(error);
  }
}

App.vue应用程序.vue

loadWeather(lat, lon) {
  API.getAddress(lat, lon).then(result => {
    this.address = result.name;
  });
  API.getForecast(lat, lon).then(result => {
    this.forecast = result;
  });
}

In addition to existing answers, this is when async..await becomes useful, since it's already used in other functions.除了现有的答案之外,这是async..await变得有用的时候,因为它已经在其他功能中使用了。 The array that Promise.all resolves to can be destructured: Promise.all解析为的数组可以被解构:

async loadWeather(lat, lon) {
  const [address, forecast] = await Promise.all([
    API.getAddress(lat, lon),
    API.getForecast(lat, lon)
  ]);
  this.address = address.name;
  this.forecast = forecast;
}

Yes you can use Promise.all to combine your calls.是的,您可以使用 Promise.all 来合并您的通话。 See below how you might do that...看看下面你会如何做到这一点......

(I'm using setTimouts in place of your fetch requests) (我正在使用 setTimouts 代替您的获取请求)

const functionA = async () => {
  await new Promise(resolve => {
    setTimeout(() => { resolve(); }, 2000);
  });

  return "A";
};

const functionB = async () => {
  await new Promise(resolve => {
    setTimeout(() => { resolve(); }, 3000);
  });

  return "B";
};

const getResults = async () => {
  const result = await Promise.all([functionA(), functionB()]);
  return result;
};

getResults().then(result => console.log(result));

View on https://codesandbox.io/s/blue-lake-qupp7?file=/src/index.js查看https://codesandbox.io/s/blue-lake-qupp7?file=/src/index.js

To translate this to your example, we can therefore do...要将其转化为您的示例,我们可以这样做...

// promise
function loadWeather(lat, lon) {
  Promise.all([
    API.getAddress(lat, lon),
    API.getForecast(lat, lon)
  ]).then(([address, forecast]) => {
    this.address = address.name;
    this.forecast = forecast;
  });
}

// or async/await
async function loadWeather(lat, lon) {
  const [address, forecast] = await Promise.all([
    API.getAddress(lat, lon),
    API.getForecast(lat, lon)
  ]);

  this.address = address.name;
  this.forecast = forecast;
}

First, decide if you want the promise to fail if any of the two API calls fail.首先,确定如果两个 API 调用中的任何一个调用失败,您是否希望 promise 失败。 Promise.all will fail in this case, Promise.allSettled will not. Promise.all在这种情况下会失败, Promise.allSettled不会。 It depends on what you want for your app.这取决于您对应用程序的要求。

To combine, you can do the following:要结合,您可以执行以下操作:

loadWeather(lat, lon) {
  Promise.all([
    API.getAddress(lat, lon),
    API.getForecast(lat, lon)
  ]).then(([addressResult, forecastResult]) => {
    this.address = addressResult.name;
    this.forecast = forecastResult;
  });
}

Promise.all returns an array of results. Promise.all返回结果数组。 This makes sense if you consider that you pass it an array of promises.如果您认为您向它传递了一系列承诺,这是有道理的。

Yes, you can write是的,你可以写

loadWeather(lat, lon) {
  Promise.all([
    API.getAddress(lat, lon),
    API.getForecast(lat, lon),
  ]).then(([addressResult, forecastResult]) => {
    this.address = addressResult.name;
    this.forecast = forecastResult;
  });
}

However, it doesn't really seem necessary, as both functions handle errors already and there doesn't seem to be a reason why the property assignments would need to wait for both promises to fulfill.然而,这似乎并不是必需的,因为这两个函数都已经处理了错误,而且似乎没有理由说明属性分配需要等待两个承诺都实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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