我有一个应该异步获取一些数据的函数。
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 的嵌套技术是否好。到目前为止,这对我来说仍然是一个很难处理的话题。
问题在于,您在
getEventsByDay
中创建了一个承诺,但该承诺有可能无法得到解决。当以下语句中的条件为假时,就会发生这种情况:
if(dailyEvents.length > 0){
您的代码中没有
else
的情况,因此该承诺处于悬而未决状态。快速解决方法是当 if
结果为空时,考虑一些值来解决此承诺,并在
dailyEvents
块中使用它调用 resolve
。不是你的问题,但你的代码正在应用 promise 构造函数反模式。简而言之,这意味着当您已经承诺合作时,您不应该这样做 else
。
new Promise()
函数,但没有从
async
运算符中受益。如果您使用它,代码的嵌套可以被扁平化并变得更具可读性。最后,尽量避免await
,而是尽可能利用
push
的力量,还有map()
。