Почему эта цепочка обещаний не возвращается последовательно? - PullRequest
0 голосов
/ 22 декабря 2019

Я пытаюсь создать цепочку обещаний, которая возвращает результаты в порядке их вызова, поскольку это важно для моего приложения. Тем не менее, несмотря на ряд попыток, я испытываю затруднения, так как вывод resultArray возвращается с заменой некоторых точек данных, что затрудняет последующую обработку. Это то, что я сейчас использую (найдено на

Promise.all(data.map( (dataPoint) => {
  return new Promise( (resolve, reject) => {
    doSomething(dataPoint).then( (result) => {
      resultArray.push(result);
      resolve();
    });
  })
})).then( () => {
    res.status(201).json({"result": resultArray});
});

. Я также попробовал следующий шаблон, но он просто возвращает [], так как обещание. Все не ожидают завершения обещаний, как предполагалось:

let p = Promise.resolve();
data.forEach(dataPoint => {
  p = p.then( () => {
    getElevation(dataPoint, options).then( (result) => {
      resultArray.push(result);
    });
  });
});

Promise.all([p]).then( () => {
  res.status(201).json({"result": resultArray});
});

ОБНОВЛЕНИЕ

Хотя на вопрос в том виде, в котором он был написан, дан ответ, теперь я понимаю, что принятый ответ не ждет возвращения каждого обещания, прежде чем следующеезапущен. Он отображает их так, чтобы вывод был в правильном порядке, но мне нужно, чтобы каждый вызов знал последние данные - как мне добиться этого кратко?

Ответы [ 2 ]

3 голосов
/ 22 декабря 2019

Не используйте forEach & [].push, если хотите получить данные в порядке. Добавьте обещания к массиву и передайте этот массив обещаний Promise.all, который будет поддерживать порядок для вас.

Кроме того, ваша строка let p = Promise.resolve() не имеет никакого смысла, она просто добавляет шум в ваш код.

Используйте .map, чтобы получить массив обещаний getElevation и передать его в Promise.all, когда он разрешит, результаты будут иметь тот же порядок, что и массив data.

const promises = data.map(dataPoint => getElevation(dataPoint, options));

Promise.all(promises).then(result => {
  res.status(201).json({ result });
});
0 голосов
/ 28 декабря 2019

Вы можете использовать шаблон async / await , если хотите, чтобы каждое обещание было полностью разрешено до следующего обещания. Таким образом, каждый звонок имеет доступ ко всем результатам предыдущих звонков.

async function run(options) {
  const results = [];
  for(let dataPoint of data) {
    const result = await getElevation(dataPoint, options);
    results.push(result);
  }
  return results;
}

run(options).then(result => {
  res.status(201).json({ result });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...