Promise.all() 永远无法解决

问题描述 投票:0回答:1

我有一个应该异步获取一些数据的函数。


  getPageEvents() {
    const promises = this.calendarPage.days.map(day => {
      return this.dataService.getEventsByDay(day)
      .then(events => {
        if(events){
          day.dailyEvents = events;
        }
      });
    });
    
    Promise.all(promises)
    .then((res) =>{
      console.log(res)
    })
    .catch(error =>{
      console.error(error)
    })
  }

getEventsByDay() 函数从 firestore 数据库返回数据:

  async getEventsByDay(day: Day): Promise<Event[] | undefined>{
    return new Promise<Event[] | undefined>((resolve) =>{
      const date: string = day.dateFormatted
      let dailyEvents: Event[] = []
      this.getEvents()
      .then(events =>{
        if(events){
          events.forEach(event =>{
            if(event.durationDates?.includes(date)){
              dailyEvents.push(event)
            }
          })
          if(dailyEvents.length > 0){
            resolve(dailyEvents)
          }
        }else{
          resolve(undefined)
        }
      })
    })
  }

问题是 Promise.all() 的 then() 块内的代码永远不会运行,即使我可以(在 UI 上)看到正在获取的数据。 这是我的 getEvents() 函数:

  async getEvents(): Promise<Event[]> {
    return new Promise<Event[]>((resolve, reject) => {
      this.getTeams()
        .then(teams => {
          const teamList: string[] = teams.map(team => team.id);
          if (teamList) {
            const promises: Promise<Event[]>[] = [];
            teamList.forEach(team => {
              promises.push(this.getEventsByTeam(team));
            })
            // Quando ho tutti gli eventi di tutti i teams
            Promise.all(promises)
              .then(teamEvents => {
                const events: Event[] = [];
                teamEvents.forEach(eventsArray => {
                  eventsArray.forEach(event => {
                    const eventList = events.map(e => e.id)
                    if(!eventList.includes(event.id)){
                      events.push(event);
                    }
                  });
                });
                resolve(events);
              })
              .catch(error => {
                reject(error);
              });
          } else {
            reject("No teams");
          }
        })
        .catch(error => {
          reject(error);
        });
    });
  }

有什么问题的猜测吗? 顺便说一句,我不知道这种 Promise 的嵌套技术是否好。到目前为止,这对我来说仍然是一个很难处理的话题。

javascript angular typescript asynchronous angular-promise
1个回答
0
投票

问题在于,您在

getEventsByDay
中创建了一个承诺,但该承诺有可能无法得到解决。当以下语句中的条件为假时,就会发生这种情况:

if(dailyEvents.length > 0){

您的代码中没有

else
的情况,因此该承诺处于悬而未决状态。
快速解决方法是当 

if

结果为空时,考虑一些值来解决此承诺,并在

dailyEvents
块中使用它调用
resolve
不是你的问题,但你的代码正在应用 

promise 构造函数反模式

。简而言之,这意味着当您已经承诺合作时,您不应该这样做 else

要重构的另一件事是您使用 

new Promise()

函数,但没有从

async
运算符中受益。如果您使用它,代码的嵌套可以被扁平化并变得更具可读性。
最后,尽量避免

await

,而是尽可能利用

push
的力量,还有
map()
    

© www.soinside.com 2019 - 2024. All rights reserved.