簡體   English   中英

如何等待承諾在地圖內解決?

[英]How to wait for a promise to resolve inside a map?

我有一個要處理的對象列表。 該對象被傳遞給一個承諾函數,該函數執行此操作並解析返回。 根據先前緩存的值,該過程可能是即時的,也可能不是。 如果已經有計算值,它會立即解析到它。 否則,它會計算。 現在我遇到的問題是在計算第一個對象的狀態之前將下一個對象傳遞給承諾:

   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;


    });
});

mapforEach這樣的數組迭代器不適用於 promise,因為它們不知道如何等待結果。 改用簡單的for循環:

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

如果你真的想要一種“功能性”的方式(並避免顯式的 async/await),你可以定義一個類似於 bluebird 的Promise.eachPromise.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);

@georg 已經發布了答案。 這需要在 for 循環中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM