在转到下一个对象后使 angular.forEach 等待承诺
Make angular.forEach wait for promise after going to next object
我有一个对象列表。对象被传递给延迟函数。我只想在上一个调用解决后才用下一个对象调用该函数。有什么办法可以做到这一点吗?
angular.forEach(objects, function (object) {
// wait for this to resolve and after that move to next object
doSomething(object);
});
检查 angular 上的 $q:
function outerFunction() {
var defer = $q.defer();
var promises = [];
function lastTask(){
writeSome('finish').then( function(){
defer.resolve();
});
}
angular.forEach( $scope.testArray, function(value){
promises.push(writeSome(value));
});
$q.all(promises).then(lastTask);
return defer;
}
在 ES2017 和 async/await
之前(请参阅下面的 ES2017 中的选项),如果您想等待承诺,则不能使用 .forEach()
,因为承诺不会阻塞。 Javascript 并且 promises 只是行不通。
您可以链接多个承诺并使承诺基础结构对它们进行排序。
可以手动迭代,只在上一个promise完成后才推进迭代
您可以使用像 async
或 Bluebird
这样的库来为您排序。
有很多不同的选择,但.forEach()
不会为你做。
这是一个使用 angular promises 的承诺链进行排序的示例(假设 objects
是一个数组):
objects.reduce(function(p, val) {
return p.then(function() {
return doSomething(val);
});
}, $q.when(true)).then(function(finalResult) {
// done here
}, function(err) {
// error here
});
并且,使用标准的 ES6 承诺,这将是:
objects.reduce(function(p, val) {
return p.then(function() {
return doSomething(val);
});
}, Promise.resolve()).then(function(finalResult) {
// done here
}, function(err) {
// error here
});
这是一个手动排序的示例(假设 objects
是一个数组),尽管这不会像上述选项那样报告完成或错误:
function run(objects) {
var cntr = 0;
function next() {
if (cntr < objects.length) {
doSomething(objects[cntr++]).then(next);
}
}
next();
}
ES2017
在 ES2017 中,async/wait
特性确实允许您在使用非基于函数的循环(例如 for
或 while
:
async function someFunc() {
for (object of objects) {
// wait for this to resolve and after that move to next object
let result = await doSomething(object);
}
}
代码必须包含在 async
函数中,然后您可以使用 await
告诉解释器在继续循环之前等待承诺解决。请注意,虽然这似乎是 "blocking" 类型的行为,但它并没有阻止事件循环。 await
.
期间事件循环中的其他事件仍然可以处理
是的,您可以使用 angular.forEach
来实现。
这里有一个例子(假设objects
是一个数组):
// Define the initial promise
var sequence = $q.defer();
sequence.resolve();
sequence = sequence.promise;
angular.forEach(objects, function(val,key){
sequence = sequence.then(function() {
return doSomething(val);
});
});
下面是如何使用 array.reduce
完成的,类似于@friend00 的回答(假设 objects
是一个数组):
objects.reduce(function(p, val) {
// The initial promise object
if(p.then === undefined) {
p.resolve();
p = p.promise;
}
return p.then(function() {
return doSomething(val);
});
}, $q.defer());
最简单的方法是创建一个函数,并在每个承诺完成后手动迭代数组中的所有对象。
var delayedFORLoop = function (array) {
var defer = $q.defer();
var loop = function (count) {
var item = array[count];
// Example of a promise to wait for
myService.DoCalculation(item).then(function (response) {
}).finally(function () {
// Resolve or continue with loop
if (count === array.length) {
defer.resolve();
} else {
loop(++count);
}
});
}
loop(0); // Start loop
return defer.promise;
}
// To use:
delayedFORLoop(array).then(function(response) {
// Do something
});
我的 GitHub 上也有示例:
https://github.com/pietervw/Deferred-Angular-FOR-Loop-Example
这可能对某些人有帮助,因为我尝试了上述几种解决方案,然后提出了我自己的实际对我有用的解决方案(其他的没有)
var sequence;
objects.forEach(function(item) {
if(sequence === undefined){
sequence = doSomethingThatReturnsAPromise(item)
}else{
sequence = sequence.then(function(){
return doSomethingThatReturnsAPromise(item)
});
}
});
它像这样对我有用。我不知道这是否是一种正确的方法,但可以帮助减少线路
function myFun(){
var deffer = $q.defer();
angular.forEach(array,function(a,i) {
Service.method(a.id).then(function(res) {
console.log(res);
if(i == array.length-1) {
deffer.resolve(res);
}
});
});
return deffer.promise;
}
myFun().then(function(res){
//res here
});
我使用一个简单的解决方案来连接打印机,等待承诺结束再转到下一个。
angular.forEach(object, function(data){
yourFunction(data)
.then(function (){
return;
})
})
我有一个对象列表。对象被传递给延迟函数。我只想在上一个调用解决后才用下一个对象调用该函数。有什么办法可以做到这一点吗?
angular.forEach(objects, function (object) {
// wait for this to resolve and after that move to next object
doSomething(object);
});
检查 angular 上的 $q:
function outerFunction() {
var defer = $q.defer();
var promises = [];
function lastTask(){
writeSome('finish').then( function(){
defer.resolve();
});
}
angular.forEach( $scope.testArray, function(value){
promises.push(writeSome(value));
});
$q.all(promises).then(lastTask);
return defer;
}
在 ES2017 和 async/await
之前(请参阅下面的 ES2017 中的选项),如果您想等待承诺,则不能使用 .forEach()
,因为承诺不会阻塞。 Javascript 并且 promises 只是行不通。
您可以链接多个承诺并使承诺基础结构对它们进行排序。
可以手动迭代,只在上一个promise完成后才推进迭代
您可以使用像
async
或Bluebird
这样的库来为您排序。
有很多不同的选择,但.forEach()
不会为你做。
这是一个使用 angular promises 的承诺链进行排序的示例(假设 objects
是一个数组):
objects.reduce(function(p, val) {
return p.then(function() {
return doSomething(val);
});
}, $q.when(true)).then(function(finalResult) {
// done here
}, function(err) {
// error here
});
并且,使用标准的 ES6 承诺,这将是:
objects.reduce(function(p, val) {
return p.then(function() {
return doSomething(val);
});
}, Promise.resolve()).then(function(finalResult) {
// done here
}, function(err) {
// error here
});
这是一个手动排序的示例(假设 objects
是一个数组),尽管这不会像上述选项那样报告完成或错误:
function run(objects) {
var cntr = 0;
function next() {
if (cntr < objects.length) {
doSomething(objects[cntr++]).then(next);
}
}
next();
}
ES2017
在 ES2017 中,async/wait
特性确实允许您在使用非基于函数的循环(例如 for
或 while
:
async function someFunc() {
for (object of objects) {
// wait for this to resolve and after that move to next object
let result = await doSomething(object);
}
}
代码必须包含在 async
函数中,然后您可以使用 await
告诉解释器在继续循环之前等待承诺解决。请注意,虽然这似乎是 "blocking" 类型的行为,但它并没有阻止事件循环。 await
.
是的,您可以使用 angular.forEach
来实现。
这里有一个例子(假设objects
是一个数组):
// Define the initial promise
var sequence = $q.defer();
sequence.resolve();
sequence = sequence.promise;
angular.forEach(objects, function(val,key){
sequence = sequence.then(function() {
return doSomething(val);
});
});
下面是如何使用 array.reduce
完成的,类似于@friend00 的回答(假设 objects
是一个数组):
objects.reduce(function(p, val) {
// The initial promise object
if(p.then === undefined) {
p.resolve();
p = p.promise;
}
return p.then(function() {
return doSomething(val);
});
}, $q.defer());
最简单的方法是创建一个函数,并在每个承诺完成后手动迭代数组中的所有对象。
var delayedFORLoop = function (array) {
var defer = $q.defer();
var loop = function (count) {
var item = array[count];
// Example of a promise to wait for
myService.DoCalculation(item).then(function (response) {
}).finally(function () {
// Resolve or continue with loop
if (count === array.length) {
defer.resolve();
} else {
loop(++count);
}
});
}
loop(0); // Start loop
return defer.promise;
}
// To use:
delayedFORLoop(array).then(function(response) {
// Do something
});
我的 GitHub 上也有示例: https://github.com/pietervw/Deferred-Angular-FOR-Loop-Example
这可能对某些人有帮助,因为我尝试了上述几种解决方案,然后提出了我自己的实际对我有用的解决方案(其他的没有)
var sequence;
objects.forEach(function(item) {
if(sequence === undefined){
sequence = doSomethingThatReturnsAPromise(item)
}else{
sequence = sequence.then(function(){
return doSomethingThatReturnsAPromise(item)
});
}
});
它像这样对我有用。我不知道这是否是一种正确的方法,但可以帮助减少线路
function myFun(){
var deffer = $q.defer();
angular.forEach(array,function(a,i) {
Service.method(a.id).then(function(res) {
console.log(res);
if(i == array.length-1) {
deffer.resolve(res);
}
});
});
return deffer.promise;
}
myFun().then(function(res){
//res here
});
我使用一个简单的解决方案来连接打印机,等待承诺结束再转到下一个。
angular.forEach(object, function(data){
yourFunction(data)
.then(function (){
return;
})
})