Я пытаюсь сделать цикл, который отправляет запросы.
Однако я хотел бы дождаться ответа на запрос, прежде чем отправлять следующий. Как я могу продолжить?
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)
));
}
});
}
Спасибо за помощь
Подпишитесь на результат http.get()
и запустите следующий «цикл» после того, как он разрешится, вместо синхронного вызова res()
в следующей строке. Однако было бы лучше знать, чего вы пытаетесь достичь, чтобы предложить лучшие альтернативы, так как это кажется неправильным.
Странно, что вы используете промисы (вместо наблюдаемые), когда уже работаете с 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)
@ Роберт Конечно, нет проблем. Пока ждете, может быть, вы сначала прочитаете этот мой ответ? stackoverflow.com/a/55686179/10959940 В первом блоке кода есть нужный вам пример.
Отлично спасибо. С наблюдаемыми это выглядит более угловатым :-)
вы можете попробовать вот так
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();
});
})
}
Все мои родительские функции должны быть асинхронными после
Да, мы можем использовать await
только внутри функции async
.
если все вызовы API не зависят друг от друга, то вы можете использовать rxJs forkjoin
для того же
@Geek_KK рад узнать, что это помогает вам :)
Спасибо за помощь всем, Наконец, я написал это в зависимости от ответа @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);
});
}
Вы можете использовать async/await? код станет более читабельным...