Javascript为承诺循环的每个项目运行异步代码

Jul*_* E. 5 javascript asynchronous node.js promise es6-promise

我有一个函数,它将一个对象传递给它,其中键和数据是一个数组.我必须调用API来获取附加信息,然后将其添加回对象并返回整个对象.

我的第一种方法是不正确的,因为我试图将数据传出.then(),但这是错误的做法.

function asignChecklistItems(taskArray) { 
    // get all the people's tasks passed in
    return new Promise(function(resolve, reject) {

        var promises = []

        // Task Array: {"Person":[tasks,tasks,tasks]}

        for (var person in taskArray) {
            var individualTaskPerson = taskArray[person]
            // get the person's tasks

            for (var individualTask in individualTaskPerson) {

                // here we get each individual task
                var task = individualTaskPerson[individualTask]

                // Check if the checklist is present, the .exists is a bool 
                if (task.checklist.exists === true) {
                //Here we push the promise back into the promise array
                // retrieve is the async function 
                     promises.push( retrieveCheckListItems(task.checklist.checklistID)
                            .then(checklistItems => {
                                var complete = []
                                var incomplete = []
                                const items = checklistItems["checkItems"];
                                for (var each in items) {
                                    const item = items[each]
                                    if (item["state"] === "complete") {
                                        complete.push(item["name"])
                                    } else {
                                        incomplete.push(item["name"])
                                    }
                                }

                                task.checklist.completeItems.push(complete)
                                task.checklist.incompleteItems.push(incomplete)
                                return taskArray // used to be: resolve(taskArray) See **EDIT**
                            })
                            .catch(err => {
                          logError(err)
                                reject(err)
                            })
             )                

                    } else {
              // There's no checklist
            }
                }
            }
        Promise.all(promises).then(function(x){
              // Here when checked, all the items are pushed to the last person inside the array. 
              // Eg. {PersonA:[tasks],PersonB:[tasks],PersonC:[tasks]}
              // All of the complete and incomplete items are added to Person C for some reason
              resolve(taskArray)

        })

        })
    }
Run Code Online (Sandbox Code Playgroud)

我已经尝试了很多方法,返回整个承诺,尝试从promise中返回(由于不允许这样做不起作用),并尝试更早地运行异步代码,并将for循环移动到promise中.他们都没有工作,这是最接近的,它为PersonC返回它.

这主要是基于其他SO问题,比如这一个,这表明如何使用Promise.All.

这是为for循环的每个元素调用promise(异步函数)的preoper方法吗?

编辑:

代码中的另一个错误是,如果有一个承诺,例如retrieveCheckListItems内部的承诺asignCheckListItems,它resolve本身不应该,但它应该return是值.我根据工作生产代码更新了代码以反映这一点.

显然我是另一个问题

小智 2

您正在执行task.checklist.completeItems.push(complete)retrieveCheckListItems .then这意味着代码是异步的。

\n

同时,var taskis 而是在循环中被分配for...in,这意味着当 your.then被触发时,for...in迭代将完成并且task将是最后分配的对象。

\n

请注意,var变量具有函数作用域,这基本上意味着您的代码相当于:

\n
function asignChecklistItems(taskArray) { \n    // get all the people's tasks passed in\n    return new Promise(function(resolve, reject) {\n\n        var promises = []\n        var individualTaskPerson;\n        var task;\n\n        ...\n
Run Code Online (Sandbox Code Playgroud)\n

通过以下方式修复:

\n
    \n
  1. 要么更改var tasklet task(如果您使用的是 ES6)。然后,这会在每个 for 循环中创建变量,而不是在封闭函数中。

    \n

    或者

    \n
  2. \n
  3. 通过替换

    \n
    for (var individualTask in individualTaskPerson) {\n\n  // here we get each individual task\n  var task = individualTaskPerson[individualTask]\n
    Run Code Online (Sandbox Code Playgroud)\n

    \n
    Object.keys(individualTaskPerson).forEach(function(individualTask) {\n    var task = individualTaskPerson[individualTask];  \n\n     ...\n});\n
    Run Code Online (Sandbox Code Playgroud)\n
  4. \n
\n

\xc2\xa0\xc2\xa0\xc2\xa0

\n

对其他 for...in 循环和变量执行相同的操作。

\n