У меня есть для каждого цикла, где я проверяю что-то внутри него. Эта проверка является асинхронной, и когда эта проверка ложна, я хочу разбить цикл. Вот мой код:
addReservation(reservation: Reservation) {
this.deskService.loadDesksWhereRangeGreater(reservation.persons).subscribe(
desks => {
if (desks.length > 0) {
for (const desk1 of desks) {
console.log('checking');
if (this.checkForAvailability(desk1, reservation)) {
console.log('found');
}
}
}
}
);
}
async checkForAvailability(desk: Desk, reservation: Reservation) {
await this.db.collection('Desks').doc(desk.id)
.collection('Reservations', ref => ref.where('timestamp', '<=', reservation.timestamp + this.reservationDelta)
.where('timestamp', '>', reservation.timestamp - this.reservationDelta))
.valueChanges().subscribe(reservations => {
if (reservations.length === 0) {
console.log('reservation possible for ' + desk.nr);
return true;
} else {
console.log(desk.nr + ' Belegt');
return false;
}
});
}
Однако часть await
не работает. Он просто выполняет цикл через цикл, не дожидаясь асинхронной функции каждой итерации.
Вам нужно await
результата checkForAvailability
:
addReservation(reservation: Reservation) {
this.deskService.loadDesksWhereRangeGreater(reservation.persons).subscribe(
async desks => {
if (desks.length > 0) {
for (const desk of desks) {
const available = await this.checkForAvailability(desk, reservation)
if (!available) { break }
}
}
}
);
}
checkForAvailability(desk: Desk, reservation: Reservation) {
// here, you need to return a promise
return new Promise(resolve => {
this.db.collection('Desks').doc(desk.id)
.collection('Reservations', ref => ref.where('timestamp', '<=', reservation.timestamp + this.reservationDelta)
.where('timestamp', '>', reservation.timestamp - this.reservationDelta))
.valueChanges().subscribe(reservations => {
resolve(reservations.length === 0)
});
})
}
const available = await this.checkForAvailability(desk, reservation);
Я получаю синтаксическую ошибку "выражение" ожидание "разрешено только в асинхронной функции". Я объявил функцию addReservation как асинхронную.
Вам нужно вернуть Promise в функции checkForAvailability
, а функция addReservation
должна быть асинхронной, чтобы использовать await
.
Оператор ожидания используется для ожидания Promise. Его можно использовать только в асинхронной функции.
Здесь пример того, как реализовать цикл async:
async function asyncLoop(){
console.log('loop 10 times')
for(let i=0; i<10; i++) await doSomethingAsync(i);
console.log('loop done!')
}
function doSomethingAsync(i){
return new Promise( function(resolve,reject){
// do your async stuff ... and then resolve()
//
// in this example i will use a timeout to simulate
// an async operation.
setTimeout( function(){
console.log(i,'done!');
resolve();
}, 1000);
})
}
asyncLoop()