Javascript运行asynchronous代码的每个项目的循环与承诺

我有一个函数,获取一个对象传入它的密钥和数据是一个数组。 我必须调用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) }) }) } 

我已经尝试了很多方法,返回了整个promise,试图从promise中返回(因为它不被允许,所以不起作用),然后尝试运行asynchronous代码,然后将for循环移到promise中。 他们都没有工作,这是最接近的,它返回PersonC的地方。

这主要是基于其他SO问题,例如这个问题,它展示了如何使用Promise.All

这是为for循环的每个元素调用承诺(asynchronous函数)的preoper方式?

编辑

代码中的另一个错误是,如果承诺承诺(例如asignCheckListItems中的asignCheckListItems ,它不应该自行resolve ,而是应该return值。 我根据工作生产代码更新了代码以反映这一点。

显然是我的另一个问题

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

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

请注意, varvariables有一个函数作用域,这基本上意味着你的代码相当于:

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

修复它:

  1. 要么更改var task let task (如果您使用的是ES6)。 然后在每个for循环中创buildvariables,而不是在封闭函数中。

    要么

  2. 通过replace

     for (var individualTask in individualTaskPerson) { // here we get each individual task var task = individualTaskPerson[individualTask] 

     Object.keys(individualTaskPerson).forEach(function(individualTask) { var task = individualTaskPerson[individualTask]; ... }); 

在循环和variables中为…执行相同的操作。