我有一个函数,它将一个对象传递给它,其中键和数据是一个数组。 我必须调用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中返回(由于不允许这样做不起作用),并尝试更早地运行异步代码,并将for循环移动到诺言。他们都没有工作,这是最接近的,它为PersonC返回它。
这主要基于其他SO问题,例如one,其中展示了如何使用Promise.All
。
这是为for循环的每个元素调用promise(异步函数)的preoper方法吗?
修改:
代码中的另一个错误是,如果有承诺提交承诺,例如retrieveCheckListItems
内的asignCheckListItems
,则不应resolve
本身,但它应该return
价值。我根据工作生产代码更新了代码以反映这一点。
显然我是另一个问题
答案 0 :(得分:2)
您正在task.checklist.completeItems.push(complete)
retrieveCheckListItems
中执行.then
,这意味着代码是异步的。
同时,在var task
循环中分配for...in
,这意味着在您的.then
被触发时,for...in
次迭代将是完成,task
将是最后分配的对象。
请注意,var
变量具有函数范围,这基本上意味着您的代码等同于:
function asignChecklistItems(taskArray) {
// get all the people's tasks passed in
return new Promise(function(resolve, reject) {
var promises = []
var individualTaskPerson;
var task;
...
修复:
将var task
更改为let task
(如果您使用的是ES6)。然后,这将在每个for循环中创建变量,而不是在封闭函数内。
或
替换
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];
...
});
对于另一个在循环和变量中执行相同操作。