Использование .map в Promise.all - PullRequest
3 голосов
/ 12 марта 2020

Итак, у меня есть несколько обещаний, которые мне нужно выполнить на init на моем Express сервере.

const dates = [];
for (var i = 0; i <= 8; i++) {
  dates.push(
    moment()
      .add(i, "days")
      .format("YYYY-MM-DD")
  );
}
const [cityName, weatherData, celestialData] = await Promise.all([
  axios.get(
    `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${myKey}`
  ),
  axios.get(
    `https://api.darksky.net/forecast/${myKey}/${latitude},${longitude}`
  ),
  dates.map(date => {
    axios.get(
      `https://api.ipgeolocation.io/astronomy?apiKey=${myKey}&lat=${latitude}&long=${longitude}&date=${date}`
    );
  })
]);

Мне нужны данные за 8 разных дней, поэтому я подумал, запустив .map с датами массив Я хотел бы получить еще один массив с разрешенным обещанием от каждого. Это не работает, как я ожидал. Как мне управлять зацикленными вызовами топора ios внутри Promise.all?

1 Ответ

4 голосов
/ 12 марта 2020

Ты действительно близко. Вы хотите

  1. Распределить массив из dates.map
  2. Захватить результаты в элементе отдыха в вашей деструктуризации
  3. Вернуть результат из axios из map обратный вызов

Примерно:

const [cityName, weatherData, ...celestialData] = await Promise.all([
// 2 −−−−−−−−−−−−−−−−−−−−−−−−−^^^
  axios.get(
    `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${myKey}`
  ),
  axios.get(
    `https://api.darksky.net/forecast/${myKey}/${latitude},${longitude}`
  ),
  ...dates.map(date => {
//^^^−−−− 1
    return axios.get(
//−−^^^^^^ 3
      `https://api.ipgeolocation.io/astronomy?apiKey=${myKey}&lat=${latitude}&long=${longitude}&date=${date}`
    );
  })
]);

celestialData будет массивом результатов для дат.

Если хотите, вы можно использовать краткую функцию стрелки для этой третьей части:

  ...dates.map(date => axios.get(
    `https://api.ipgeolocation.io/astronomy?apiKey=${myKey}&lat=${latitude}&long=${longitude}&date=${date}`
  )

Примечание: ваш текущий способ создания массива dates вполне подходит, но если вы хотите, вы можете использовать Array.from способность картирования:

const dates = Array.from(
  Array(9),
  (_, i) => moment().add(i, "days").format("YYYY-MM-DD")
);

Так как Seblor не опубликовал это как ответ, вот их подход (который кажется мне лучше поскольку он избегает расширения массива только для того, чтобы снова собрать его обратно с элементом rest в процессе деструктуризации):

const [cityName, weatherData, celestialData] = await Promise.all([
  axios.get(
    `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${myKey}`
  ),
  axios.get(
    `https://api.darksky.net/forecast/${myKey}/${latitude},${longitude}`
  ),
  Promise.all(dates.map(date => {
    return axios.get(
      `https://api.ipgeolocation.io/astronomy?apiKey=${myKey}&lat=${latitude}&long=${longitude}&date=${date}`
    );
  }))
]);
...