admin管理员组

文章数量:1359230

I have two promises from two different API calls in my VUE JS app, I was thinking maybe both could be bined using a promise.all() approach? If so how could I do this?

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

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

I have two promises from two different API calls in my VUE JS app, I was thinking maybe both could be bined using a promise.all() approach? If so how could I do this?

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

loadWeather(lat, lon) {
  API.getAddress(lat, lon).then(result => {
    this.address = result.name;
  });
  API.getForecast(lat, lon).then(result => {
    this.forecast = result;
  });
}
Share Improve this question edited Apr 20, 2020 at 13:38 Rob asked Apr 18, 2020 at 20:17 RobRob 2138 silver badges17 bronze badges 4
  • It's not entirely clear what you mean by 'bined'. What are you trying to achieve and why? – skirtle Commented Apr 18, 2020 at 20:22
  • I have two promises in my loadWeather method, I was wondering if a promise.all would be of use here? – Rob Commented Apr 18, 2020 at 20:25
  • @Rob What is the supposed advantage of bining them? What do you want to achieve that your current code doesn't do? – Bergi Commented Apr 18, 2020 at 20:29
  • Better code standards? If the code is acceptable like this then I'll roll with it. I'm not too familiar with bining promises as I'm learning. – Rob Commented Apr 18, 2020 at 20:32
Add a ment  | 

4 Answers 4

Reset to default 5

In addition to existing answers, this is when async..await bees useful, since it's already used in other functions. The array that Promise.all resolves to can be destructured:

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;
}

First, decide if you want the promise to fail if any of the two API calls fail. Promise.all will fail in this case, Promise.allSettled will not. It depends on what you want for your app.

To bine, 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. 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.

Yes you can use Promise.all to bine your calls. See below how you might do that...

(I'm using setTimouts in place of your fetch requests)

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

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;
}

本文标签: javascriptCombining two promises using promiseallStack Overflow