В цикле Promise, как ждать ответа на запрос?

Я пытаюсь сделать цикл, который отправляет запросы.

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

 private start(): Promise<string> {
    return new Promise((resolve, reject) => {
      for (let j = 0, p = Promise.resolve(); j < count; j++) {
        p = p.then(_ => new Promise<null>(res =>
          setTimeout(() => {
            if (j === (count - 1)) {
              resolve();
            } else {
              this.http.get();
              res();
            }
          }, 1000)
        ));
      }
    });
  }

Спасибо за помощь

Вы можете использовать async/await? код станет более читабельным...

Mario Vernari 30.05.2019 11:24

Подпишитесь на результат http.get() и запустите следующий «цикл» после того, как он разрешится, вместо синхронного вызова res() в следующей строке. Однако было бы лучше знать, чего вы пытаетесь достичь, чтобы предложить лучшие альтернативы, так как это кажется неправильным.

Capricorn 30.05.2019 11:26
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
2
2 642
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Странно, что вы используете промисы (вместо наблюдаемые), когда уже работаете с Angular.

В любом случае, когда дело доходит до повторения промисов, вы можете использовать Обещание.все. Мы помещаем промисы в список, а затем разрешаем промисы только после того, как все итерации цикла for были выполнены.

const promisesList = [];
for (let j = 0; j < count; j++) {
  promisesList.push(promise);
}
Promise.all(promises).then(res => {
  // handle the rest here
})

Как предложил @robert, я включу реализацию того, как мы можем решить вышеизложенное, используя observables/forkjoin. Вам нужно будет импортировать forkJoin из пакета rxjs перед его использованием.

Подобно Promises.all(), forkJoin() ожидает завершения цикла for, прежде чем вернуть наблюдаемые значения.

import { forkJoin } from 'rxjs';

.
.
.

start() {
  const observablesList = [];
  const sendRequest = this.someService.someRequest(); // observable

  for (let j = 0; j < count; j++) {
    observablesList.push(sendRequest);
  }

  forkJoin(observablesList).subscribe(res => {
    console.info(res);
    //handle the rest
  });
}

Можете ли вы предоставить образец с наблюдаемыми (возможно, с помощью forkJoin)

robert 30.05.2019 11:40

@ Роберт Конечно, нет проблем. Пока ждете, может быть, вы сначала прочитаете этот мой ответ? stackoverflow.com/a/55686179/10959940 В первом блоке кода есть нужный вам пример.

wentjun 30.05.2019 11:44

Отлично спасибо. С наблюдаемыми это выглядит более угловатым :-)

robert 30.05.2019 11:52

вы можете попробовать вот так

async mainFunction () {
for(let i = 0; i < count; i++) {
    await apiCallFunction();
    // other code 
}
}

apiCallFunction() {
 return new Promise((resolve, reject) => {
    this.http.get().subscribe(resp => {
      resolve();
    });
 })
}

Все мои родительские функции должны быть асинхронными после

Shidomaru NeveRage 30.05.2019 11:41

Да, мы можем использовать await только внутри функции async.

Yash Rami 30.05.2019 11:46

если все вызовы API не зависят друг от друга, то вы можете использовать rxJs forkjoin для того же

Yash Rami 30.05.2019 11:48

@Geek_KK рад узнать, что это помогает вам :)

Yash Rami 16.07.2021 11:47
Ответ принят как подходящий

Спасибо за помощь всем, Наконец, я написал это в зависимости от ответа @Capricorn

      private start(): Promise<string> {
    return new Promise((resolve, reject) => {
      for (let j = 0, p = Promise.resolve(); j < 10; j++) {
        p = p.then(() => new Promise<null>((res) => {
          this.get().then(() => res());
        }));
      }
    });
  }

  private get(): Promise<string> {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        alert('hello');
        resolve();
      }, 3000);
    });
  }

Другие вопросы по теме