JavaScript: Promise.All () и Async / Await и Map () - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь понять, почему следующие два кодовых блока дают разные результаты.

Первый блок кода работает как положено и возвращает массив провайдеров, отыскиваемых из базы данных.С другой стороны, второй блок кода возвращает массив функций.Я чувствую, что мне не хватает чего-то простого в моем понимании Promise.all () и async / await.

Различия в блоках кода:

  • Блок 1: Массив функций обещаний создается и затем оборачивается в асинхронные функции с помощью оператора map.

  • Блок 2: Массив функций обещаний создается как асинхронные функции.Поэтому оператор map не вызывается.

Если вы не знакомы с библиотекой Sequelize, вызываемый метод findOne () возвращает обещание.

Также стоит упомянуть, я знаю, что мог бы использовать один запрос поиска с предложением «name in» и «name in» для получения одинаковых результатов без создания массива обещаний для нескольких запросов select.Я делаю это просто как учебное упражнение на async / await и Promise.all ().

БЛОК КОДА 1: Использование map () внутри Promise.all ()

private async createProfilePromises(profiles){

    let profileProviderFindPromises = [];

    //Build the Profile Providers Promises Array.
    profiles.forEach(profile => {
        profileProviderFindPromises.push(
            () => {
                return BaseRoute.db.models.ProfileProvider.findOne({
                    where: {
                        name: {[BaseRoute.Op.eq]: profile.profileProvider}
                    }
                })}
        );
    });

    //Map and Execute the Promises
    let providers = await Promise.all(profileProviderFindPromises.map(async (myPromise) =>{
        try{
            return await myPromise();
        }catch(err){
            return err.toString();
        }
    }));

    //Log the Results
    console.log(providers);
}

БЛОК КОДА 2: Добавление асинхронной функции без использованиякарта ()

private async createProfilePromises(profiles){

    let profileProviderFindPromises = [];

    //Build the Profile Providers Promises Array.
    profiles.forEach(profile => {
        profileProviderFindPromises.push(
            async () => {
                try{
                    return await BaseRoute.db.models.ProfileProvider.findOne({
                        where: {
                            name: {[BaseRoute.Op.eq]: profile.profileProvider}
                        }
                    });
                }catch(e){
                    return e.toString();
                }
            }
        );
    });

    //Execute the Promises
    let providers = await Promise.all(profileProviderFindPromises);

    //Log the Results
    console.log(providers);
}

1 Ответ

0 голосов
/ 12 ноября 2018

Ваш код в основном сводится к:

  const array = [1, 2, 3];

  function fn() { return 1; }

  array.map(fn); // [1, 1, 1]

  array.push(fn);
  console.log(array); // [1, 2, 3, fn]

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

  array.push(fn());

или в вашем случае:

 array.push((async () => { /*...*/ })());

Как бы я написал ваш код:

 return Promise.all(profiles.map(async profile => {
   try{
     return await BaseRoute.db.models.ProfileProvider.findOne({
       where: {
         name: { [BaseRoute.Op.eq]: profile.profileProvider }
       }
     });
  } catch(e) {
    // seriously: does that make sense? :
    return e.toString();
  }
}));
...