如何等待包裹在 for 循环中的多个异步方法的结果?
How to wait for results from multiple async methods wrapped in a for loop?
我正在开发一种搜索算法,它可以搜索 3 个数据库并打印出结果。代码的一般结构如下所示:
for(type in ["player", "team", "event"]){
this.searchService.getSearchResult(type).toPromise()
.then(search_result => {
if(type == "player"){
this.player_search_results_full = this.getPlayerSearchResults(search_result, search_string);
}
if(type == "team"){
this.team_search_results_full = this.getTeamSearchResults(search_result, search_string);
}
if(type == "event"){
this.event_search_results_full = this.getEventSearchResults(search_result, search_string);
}
})
}
// this.getFinalDisplayResults()
getFinalDisplayResults(){
// Do some actions on <type>_search_results_full lists
}
那些 <type>_search_results_full
将是一个列表,其中包含 search_string 的完整匹配列表。然后我想等待所有这些列表被填充,然后 运行 通过另一种方法 getFinalDisplayResults
它们从这些完整列表中选择总共显示 X 个结果。
我面临的问题是 this.getFinalDisplayResults()
在那些 <type>_search_results_full
列表已满之前执行。我尝试将所有内容放在 for 循环中的单独方法 getFullResults()
中,然后执行如下操作:
async getFinalDisplayResults(){
await getFullResults()
// Do something
}
但这似乎不起作用,因为添加一些日志表明 getFullResults() 中的 for 循环在没有填充列表的情况下完成。
我对 toPromise() 和异步方法不是很了解,所以我确定我只是错误地处理了这个问题。有人可以帮助我了解我应该做什么吗?
我认为您正在寻找的是 Promise.all
,因为它需要一组 Promise 并解析为一组结果。
以你的例子为例,它可能是这样的:
const results = await Promise.all(["player", "team", "event"].map( type =>
this.searchService.getSearchResult(type).toPromise()
))
我们可以稍微清理一下,主要是迭代随类型数组变化的内容。
const promises = [
{ type: 'player', method: 'getPlayerSearchResults'},
{ type: 'team', method: 'getTeamSearchResults'},
{ type: 'event', method: 'getEventSearchResults'}
].map(obj => {
return this.searchService.getSearchResult(obj.type).toPromise().then(search_result => {
return this[obj.method].bind(this)(search_result, search_string);
})
});
return Promise.all(promises);
我想我知道你试图实现什么,以及你遇到的问题,this.getFinalDisplayResults()
在你得到结果之前执行,因为 for 循环内的逻辑是异步的,所以修复是。
async function getDataFromBackend () {
for(let type in ["player", "team", "event"]) {
const searchResult = await this.searchService.getSearchResult(type).toPromise()
if(type === "player")
this.player_search_results_full = this.getPlayerSearchResults(searchResult, search_string);
if(type === "team")
this.team_search_results_full = this.getTeamSearchResults(searchResult, search_string);
if(type === "event")
this.event_search_results_full = this.getEventSearchResults(searchResult, search_string);
}
}
async function getFinalDisplayResults() {
await getDataFromBackend(); // this will ensure you have the data, before you do the rest of the process
//rest of the logic here
}
我正在开发一种搜索算法,它可以搜索 3 个数据库并打印出结果。代码的一般结构如下所示:
for(type in ["player", "team", "event"]){
this.searchService.getSearchResult(type).toPromise()
.then(search_result => {
if(type == "player"){
this.player_search_results_full = this.getPlayerSearchResults(search_result, search_string);
}
if(type == "team"){
this.team_search_results_full = this.getTeamSearchResults(search_result, search_string);
}
if(type == "event"){
this.event_search_results_full = this.getEventSearchResults(search_result, search_string);
}
})
}
// this.getFinalDisplayResults()
getFinalDisplayResults(){
// Do some actions on <type>_search_results_full lists
}
那些 <type>_search_results_full
将是一个列表,其中包含 search_string 的完整匹配列表。然后我想等待所有这些列表被填充,然后 运行 通过另一种方法 getFinalDisplayResults
它们从这些完整列表中选择总共显示 X 个结果。
我面临的问题是 this.getFinalDisplayResults()
在那些 <type>_search_results_full
列表已满之前执行。我尝试将所有内容放在 for 循环中的单独方法 getFullResults()
中,然后执行如下操作:
async getFinalDisplayResults(){
await getFullResults()
// Do something
}
但这似乎不起作用,因为添加一些日志表明 getFullResults() 中的 for 循环在没有填充列表的情况下完成。
我对 toPromise() 和异步方法不是很了解,所以我确定我只是错误地处理了这个问题。有人可以帮助我了解我应该做什么吗?
我认为您正在寻找的是 Promise.all
,因为它需要一组 Promise 并解析为一组结果。
以你的例子为例,它可能是这样的:
const results = await Promise.all(["player", "team", "event"].map( type =>
this.searchService.getSearchResult(type).toPromise()
))
我们可以稍微清理一下,主要是迭代随类型数组变化的内容。
const promises = [
{ type: 'player', method: 'getPlayerSearchResults'},
{ type: 'team', method: 'getTeamSearchResults'},
{ type: 'event', method: 'getEventSearchResults'}
].map(obj => {
return this.searchService.getSearchResult(obj.type).toPromise().then(search_result => {
return this[obj.method].bind(this)(search_result, search_string);
})
});
return Promise.all(promises);
我想我知道你试图实现什么,以及你遇到的问题,this.getFinalDisplayResults()
在你得到结果之前执行,因为 for 循环内的逻辑是异步的,所以修复是。
async function getDataFromBackend () {
for(let type in ["player", "team", "event"]) {
const searchResult = await this.searchService.getSearchResult(type).toPromise()
if(type === "player")
this.player_search_results_full = this.getPlayerSearchResults(searchResult, search_string);
if(type === "team")
this.team_search_results_full = this.getTeamSearchResults(searchResult, search_string);
if(type === "event")
this.event_search_results_full = this.getEventSearchResults(searchResult, search_string);
}
}
async function getFinalDisplayResults() {
await getDataFromBackend(); // this will ensure you have the data, before you do the rest of the process
//rest of the logic here
}