Почему это обещание пропускает цикл forEach

#javascript #typescript

#javascript #typescript

Вопрос:

У меня проблема с этим кодом. Я пытаюсь вернуть обещание, но по какой-то причине, когда я его отлаживаю, оно «пропускает» forEach и отклоняет функцию. Что я делаю не так?

 removeOldBookings(rooms: Room[]) {
  return new Promise((resolve, reject) => {
    const today = new Date();
    const roomsHolder = [];
    rooms.forEach(roomElement => {
      const bookingFiltered = roomElement[1].filterRoom.filter(finder => finder.provider.toUpperCase() === 'SELF');
      if (new Date(bookingFiltered.dateEnd) > today) {
        const obj = {...roomElement[1], hostBookings: [...bookingFiltered]};
        roomsHolder.push(obj);
      }
    });
    if (roomsHolder.length) {
      resolve(roomsHolder);
    } else {
      reject('error');
    }
  });
}
  

Комментарии:

1. filter() возвращает массив. new Date(array.nonExistentProperty) вернет недопустимую дату, поэтому if() никогда не будет true

2. здесь не должно быть причины для обещания, поскольку ничто не является асинхронным.

3. @DanielA. Белый, это хороший момент!

Ответ №1:

Как сказал charlietfl, filter in roomElement[1].filterRoom.filter(...) возвращает массив, так bookingFiltered что это массив. bookingFiltered.dateEnd это undefined приводит к недопустимой дате, которая преобразуется в NaN при использовании с > (больше). NaN никогда не будет больше, чем что-либо, поэтому код в if блоке никогда не будет выполнен и roomsHolder всегда будет пустым.

Если вы хотите получить первый элемент массива, который соответствует предикату, используйте find вместо:

 const bookingFiltered = roomElement[1].filterRoom.find(finder => finder.provider.toUpperCase() === 'SELF')
  

Кроме того, как сказал Дэниел А. Уайт, вам не нужно возвращать обещание здесь. Вы можете просто вернуться roomsHolder и бросить 'error' :

 removeOldBookings(rooms: Room[]) {
  const today = new Date();
  const roomsHolder = [];
  rooms.forEach(roomElement => {
    const bookingFiltered = roomElement[1].filterRoom.find(finder => finder.provider.toUpperCase() === 'SELF');
    if (new Date(bookingFiltered.dateEnd) > today) {
      const obj = {...roomElement[1], hostBookings: [...bookingFiltered]};
      roomsHolder.push(obj);
    }
  });
  if (roomsHolder.length) {
    return roomsHolder;
  } else {
    throw 'error';
  }
}
  

Если по какой-то причине вы должны вернуть обещание, вы также можете создать метод async или return Promise.resolve(roomsHolder) и Promise.reject('error') вместо того, чтобы оборачивать все в конструкторе promise.