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

时间:2019-12-02 10:58:00

标签: javascript angular typescript

我有一个要处理的对象列表。该对象被传递给一个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}

      ];

现在,即使在某个实例上需要花费一分钟的时间来计算,我也要绝对等待该承诺在循环期间解决。同一组中的所有人都具有相同的状态。因此,promise检查是否已经计算了一个组。如果是,则将其返回。否则,它进行计算。这就是问题所在。在杰西卡1完成之前,其他人已通过。

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


    });
});

4 个答案:

答案 0 :(得分:8)

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

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

如果您确实想要“功能性”方式(并避免显式异步/等待),则可以定义类似于蓝鸟的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(...)

答案 1 :(得分:0)

使它与async/await同步工作。 (在这种情况下,for..of.map更适合)

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

答案 2 :(得分:0)

您可以尝试

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;
  });
}

答案 3 :(得分:0)

您可以使用递归函数:

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);