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

Jar*_*ton 4 javascript asynchronous promise async-await sequelize.js

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

第一个代码块按预期工作,并返回从数据库中查找的提供程序数组。另一方面,代码块二返回一个函数数组。我觉得我在理解 Promise.all() 和 async/await 时缺少一些简单的东西。

代码块的区别是:

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

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

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

另外值得一提的是,我知道我可以使用带有“name in” where 子句的单个查找查询来获得相同的结果,而无需为多个选择查询创建一组 promise。我这样做只是作为 async/await 和 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);
}
Run Code Online (Sandbox Code Playgroud)

代码块 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);
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*lms 6

您的代码基本上归结为:

  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]
Run Code Online (Sandbox Code Playgroud)

你推送一个函数(不管是async不是无关紧要),而不是你想推送调用函数的结果:

  array.push(fn());
Run Code Online (Sandbox Code Playgroud)

或者在你的情况下:

 array.push((async () => { /*...*/ })());
Run Code Online (Sandbox Code Playgroud)

我将如何编写您的代码:

 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();
  }
}));
Run Code Online (Sandbox Code Playgroud)