JavaScript:Promise.All()和Async / Await和Map()

时间:2018-11-12 20:52:51

标签: javascript asynchronous promise async-await sequelize.js

我试图理解为什么以下两个代码块产生不同的结果。

代码块1可以正常工作,并返回从数据库中查找的提供程序数组。另一方面,代码块2返回函数数组。我觉得我对Promise.all()和async / await的理解中缺少一些简单的东西。

代码块中的差异是:

  • 块1:创建promise函数数组,然后使用map运算符将其包装在异步函数中。

  • 块2:将Promise函数数组创建为异步函数。因此,不会调用地图运算符。

如果您不熟悉Sequelize库,则被调用的findOne()方法将返回一个Promise。

还值得一提的是,我知道我可以使用带有“ name in” where子句的单个查找查询来获得相同的结果,而无需为多个选择查询创建承诺数组。我只是作为异步/等待和Promise.all()的学习练习来执行此操作。

代码块1:在Promise.all()中使用map()

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:不使用map()添加异步功能

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 :(得分:2)

您的代码基本上可以归结为:

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