如何等待承诺在地图内解决?



我有一个要处理的对象列表。该对象被传递给一个 promise 函数,该函数执行这个和那个并解析回来。该过程可以是即时的,也可以不是,具体取决于先前缓存的值。如果已经有计算值,它将立即解析为该值。否则,它将计算。现在我遇到的问题是,在计算第一个对象的状态之前,下一个对象被传递给 promise:

let people = [ 
{groupId: 1, name: 'Jessica Coleman', status: 'Unknown', id:1}
{groupId: 1, name: 'Eric Tomson', status: 'Unknown', id:2}
{groupId: 1, name: 'Samuel Bell', status: 'Unknown', id:3}
];

现在我想绝对等待承诺在循环期间解析,即使承诺需要一分钟才能在实例上计算。同一组的所有人都具有相同的状态。因此,承诺检查是否已计算出组。如果是,则返回它。否则,它会计算。这就是问题所在。在杰西卡1完成之前,其他人都通过了。

people.map(function(person) {
// return the promise to array
this.calculatorService
.getStatus(person)
.then(function(res) {
person.status = res;

});
});

mapforEach这样的数组迭代器不能与 promise 一起使用,因为它们不知道如何等待结果。请改用简单的for循环:

for (let person of people)
person.status = await this.calculatorService.getStatus(person)

如果你真的想要一个"功能"的方式(并避免显式的async/await(,你可以定义一个类似于蓝鸟Promise.each的函数:

Promise.each = function(ary, fn) {
return ary.reduce((p, x) => p.then(() => fn(x)), Promise.resolve(null))
}

并像这样应用它:

function setStatus(person) {
return calculatorService
.getStatus(person)
.then(res => person.status = res);
}
Promise.each(people, setStatus).then(...)

使其与async/await同步工作。(顺便说一句,在这种情况下,for..of.map更适合(。

for (let person of people) {
person.status = await this.calculatorService.getStatus(person);
})

你可以这样尝试

let people = [ 
{groupId: 1, name: 'Jessica Coleman', status: 'Unknown', id:1},
{groupId: 1, name: 'Eric Tomson', status: 'Unknown', id:2},
{groupId: 1, name: 'Samuel Bell', status: 'Unknown', id:3}
];

for (let person of people) {
await this.calculatorService.getStatus(person).then(res => {
person.status = res;
});
}

您可以使用递归函数:

let people = [ 
{groupId: 1, name: 'Jessica Coleman', status: 'Unknown', id:1},
{groupId: 1, name: 'Eric Tomson', status: 'Unknown', id:2},
{groupId: 1, name: 'Samuel Bell', status: 'Unknown', id:3}
];
function recCalculatorService(people) {
if (!people || !people.length) {
return;
}
this.calculatorService
.getStatus(people.shift())
.then(function(res) {
person.status = res;
recCalculatorService(people);
});
}
// use people.slice() if you want to keep people array intact
recCalculatorService(people);

最新更新