【问题标题】:Struggling to get my promises to work in an array loop努力让我的承诺在数组循环中工作
【发布时间】:2021-02-06 22:54:21
【问题描述】:

我已经为这个问题苦苦挣扎了一个星期,并且研究自己濒临死亡。我是一个完全的新手。我已经设法抓住了承诺的关键,但我没有看到如何将它包含在一个循环中。 我有一个正在查看数组的应用程序。针对 mongoose 数据库对阵列进行了一些验证(运行需要时间)。我正在尝试根据其中的一些验证将项目推送到新数组中。由于循环中的控制台日志,我知道验证正在工作。但是我的最终数组并没有等待循环完成。这意味着我需要将循环放入一个承诺中,或者我认为,但问题是我不知道如何解决它。当前输出是一个空白数组,而不是经过验证的数组。这是我的代码:

//dummy data of an array - this is originally extracted from a mongoose DB and works (it's my first promise).
        const appArray = ["5f8f25d554f1e43f3089ea5d",
        "5f8f25e854f1e43f3089ea5e",
        "5f8f25f454f1e43f3089ea5f",
        "5f8f314ab92c7f406f28b83a",
        "5f8fe50a9d44694cad91a01b",
        "5f92e8a75d848870e015dff3",
        "5f92e8b35d848870e015dff4",
        "5f92e8cb5d848870e015dff5",
        "5f8fe51d9d44694cad91a01c"];

    //the second promise takes the array above and validates it against another collection on mongoose
    function myPromise2 (response){
        return new Promise((resolve, reject) => {
            let appoints = [];
                response.forEach(e => {
                    //loop through each item of the array and look against Appointment collection
                    Appointment.findById(e, function(err, foundApp){
                        //some validation supposed to happen here and then pushed into a new array
                        appoints.push(foundApp);
                        console.log(appoints);
                    })
            }) 
            //once completed supposed to resolve and return
            resolve(appoints);
        })
    };

    myPromise2(appArray).then((response) => {console.log(response)});

【问题讨论】:

    标签: javascript node.js arrays loops es6-promise


    【解决方案1】:

    这是我的建议:

     const appArray = [
                  "5f8f25d554f1e43f3089ea5d",
                  "5f8f25e854f1e43f3089ea5e",
                  "5f8f25f454f1e43f3089ea5f",
                  "5f8f314ab92c7f406f28b83a",
                  "5f8fe50a9d44694cad91a01b",
                  "5f92e8a75d848870e015dff3",
                  "5f92e8b35d848870e015dff4",
                  "5f92e8cb5d848870e015dff5",
                  "5f8fe51d9d44694cad91a01c"
                 ];
                    
     function myPromise2 (response){
         return Promise.all(response.map(id) => {
            return Appointment.findById(id).exec();
            })
         };
                    
     myPromise2(appArray)
      .then(console.log) // response array
      .catch(// handle errors)
     // you can also async/await the calling part
    

    您也可以使用以下之一:

    1. Promise.allSettled
    2. Prmoise.any (es2021)
    3. Promise.race

    这仅取决于您希望如何处理响应/失败。

    【讨论】:

      【解决方案2】:

      指向地址:

      • 使用猫鼬通过.exec() 方法提供的promise。这样你就不需要new Promise
      • 将这些单独的 Promise 收集到一个数组中(使用.map 而不是.forEach),并将这个数组传递给Promise.all

      如果您这样做,myPromise2 的代码将简化为以下内容:

      function myPromise2 (response){
          return Promise.all(response.map(e => Appointment.findById(e).exec()));
      }
      

      【讨论】:

        【解决方案3】:

        可以考虑 Async/Await 并查看 Async_await。这有望解决您的所有问题

        了解一下 JS 事件循环系统的工作原理可能是个好主意guide here

        【讨论】:

        • 这使得通过使用 await 关键字等待一些异步任务完成,首先学习 Promise 和异步任务变得更容易。
        【解决方案4】:

        这是一个应该可以工作的例子。为数组中的每个元素添加一个 Promise,如果所有 Promise 都已解析,则解析外部函数。

        // dummy data of an array - this is originally extracted from a mongoose DB and works (it's my first promise).
        const appArray = ["5f8f25d554f1e43f3089ea5d",
        "5f8f25e854f1e43f3089ea5e",
        "5f8f25f454f1e43f3089ea5f",
        "5f8f314ab92c7f406f28b83a",
        "5f8fe50a9d44694cad91a01b",
        "5f92e8a75d848870e015dff3",
        "5f92e8b35d848870e015dff4",
        "5f92e8cb5d848870e015dff5",
        "5f8fe51d9d44694cad91a01c"];
        
        // the second promise takes the array above and validates it against another collection on mongoose
        function myPromise2 (response) {
          let appoints = [];
          response.forEach(e => {
            appoints.push(new Promise((resolve) => {
              //loop through each item of the array and look against Appointment collection
              Appointment.findById(e, function(err, foundApp) {
                //some validation supposed to happen here and then pushed into a new array
                resolve(foundApp);
              })
            }))
          })
          return Promise.all(appoints)
        };
        
        myPromise2(appArray).then((response) => {console.log(response)});
        

        【讨论】:

        • 非常感谢您提供此解决方案。令人惊讶的是,一行简单的代码如何解决了我的问题,我为此奋斗了一周。更重要的是,它让我对未来的问题有了更好的洞察力。非常感谢。
        猜你喜欢
        • 2012-01-15
        • 1970-01-01
        • 2019-04-24
        • 2020-08-04
        • 2023-03-18
        • 2021-02-25
        • 1970-01-01
        • 2021-10-27
        • 2018-07-17
        相关资源
        最近更新 更多