因此,在这种情况下,我需要构建一个对象,然后将一些项目注入到该对象中,然后进行API调用,并将API的响应注入到该对象中。它是一个复杂的对象,因此我们假设它没问题,但是无论如何,我认为我需要同步执行这三件事,并且使用array.forEach
意味着它们异步运行。
我希望我的示例足够简单易懂,但基本上我会做三件事:
创建一个空的班级/教室数组
遍历类ID数组,并为每个Class
创建一个对象
遍历Students
数组并将其推入students
对象内的Class
数组
遍历Options
数组并将其推入options
对象内的Class
数组
最后,对于每个类,我都有类似以下内容的东西:
{
class_id: "abc123",
students: [{}, {}, {}],
options: [{}, {}, {}]
}
最后,这是我的代码:
// Create Array of Class Objects
var classes = [];
function processArray(array, func) {
return $q(function(resolve, reject) {
array.forEach(function(item, index) {
func(item);
if (index === (array.length - 1)) resolve();
})
})
}
// Create Courier Objects
processArray(classIds, function(id) {
classes.push({class_id: id, students: [], options: []});
}).then(function(response) {
// Inject Students into each Class
processArray(students, function(students) {
_.find(classes, {'class_id': student.class_id}).students.push(student);
}).then(function(response) {
// Inject classOptions into each Class
processArray(classOptions, function(classOption) {
_.find(classes, {'class_id': classOption.class_id}).classOptions.push(classOption);
}).then(function(response) {
// Print the classes
console.log(classes);
})
})
});
我已经创建了一个同步执行该函数的函数,但是我想知道是否有人可以想到一种更清洁,更高效的方法来完成上述任务。似乎非常hacky,如果我正确地安排了功能,也许我什至不需要同步执行。
最佳答案
使用基于Promise的API返回数组processArray
函数返回一个解析为null的promise。
//WRONG
//Returns a promise that resolves to null
//
function processArray(array, func) {
return $q(function(resolve, reject) {
array.forEach(function(item, index) {
func(item);
if (index === (array.length - 1)) resolve();
})
})
}
要返回解析为数组的promise,请使用
$q.all
。//RIGHT
//Returns a promise that resolves to an array
//
function processArray(array, func) {
var promiseArray = [];
array.forEach(function(item, index) {
promiseArray.push($q.when(func(item));
});
return $q.all(promiseArray);
}
无论哪种情况,无论
func(item)
返回值还是承诺,$q.when
都将返回承诺。请注意,
$q.all
没有弹性。它将解决使用值数组满足的情况,或者将解决因第一个错误而被拒绝的情况。processArray(array, func)
.then( function onFulfilled(dataList) {
//resolves with an array
$scope.dataList = dataList;
}).catch( function onRejected(firstError) {
console.log(firstError);
});
有关更多信息,请参见AngularJS $q Service API Reference。
关于javascript - 与$ q同步使用forEach,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36337960/