javascript中的异步/等待循环

问题描述

我有一个react组件,可以在安装组件时运行此功能。

 function getListOfItems(){
    let result = [];
    for(let i=0 ; i<5 ; i++){
        /**
         * code to assign values to some variables namely param1,param2
         */
        getDetails(param1,param2);
    }
    const getDetails = async (param1,param2) => {
        let list = await getAPIresults(param1)
        result.push(list);
        if(result.length === 5){
            //code to update a hook which causes render and displays the text in results array
        }
    }
 }
  
 useEffect(() => {
   getListOfItems()
 },[])

因此代码正在运行,但是结果数组具有随机顺序的数据。例如,结果数组可能看起来像这样的 [2,5,1,3,4] ,在这里我希望它看起来像这样的 [1,2,4,5 ] ,这意味着上面的代码未按其到达顺序运行异步任务。所以有人可以帮我解决这个问题,我希望代码按到达的顺序发出异步请求。

解决方法

您需要再次使用await关键字来等待循环的每次迭代完成,然后才能继续进行下一个循环。

await getDetails(param1,param2)

但是由于您只能在异步函数中执行此操作,因此您的getListOfItems也需要是异步函数。

async function getListOfItems(){
    let result = [];
    for(let i=0 ; i<5 ; i++){
        await getDetails(param1,param2);
    }
    const getDetails = async (param1,param2) => {
        let list = await getAPIresults(param1)
        result.push(list);
        if(result.length === 5){}
    }
 }
,

因此代码正在运行,但是结果数组具有随机顺序的数据。

这是因为您的循环反复调用getDetails,以等待上一个调用完成。因此,所有通话都重叠并开始比赛。

如果可以重叠,但是您需要按顺序排列结果,请使用Promise.all并让getDetails返回其结果(而不是直接推送它们)。

如果您不能getListOfItems设为async函数:

const getDetails = async (param1,param2) => {
    let list = await getAPIresults(param1)
    if(result.length === 5){
        //code to update a hook which causes render and displays the text in results array
    }
    return list;
}
const promises = [];
for (let i = 0; i < 5; ++i) {
    promises.push(getDetails(param1,param2));
}
Promise.all(promises)
.then(results => {
    // `results` is an array of the results,in the same order as the
    // array of promises
})
.catch(error => {
    // Handle/report error
});

如果您可以(呼叫者将通过拒绝来自getListOfItems的承诺来处理传播给它的任何错误):

const getDetails = async (param1,param2));
}
const results = await Promise.all(promises)
// `results` is an array of the results,in the same order as the
// array of promises

如果您不希望它们重叠,而是一个接一个地运行,那么最好的选择是使用async函数进行循环。

如果您不能getListOfItems设为async函数:

const getAllResults = async function() {
    const results = [];
    for (let i = 0; i < 5; ++i) {
        results.push(await getDetails(param1,param2));
    }
    return results;
}
const getDetails = async (param1,param2) => {
    let list = await getAPIresults(param1)
    if(result.length === 5){
        //code to update a hook which causes render and displays the text in results array
    }
    return list;
}
getAllResults()
.then(results => {
    // `results` is an array of the results,in order
})
.catch(error => {
    // Handle/report error
});

如果您可以(呼叫者将通过拒绝来自getListOfItems的承诺来处理传播给它的任何错误):

const results = [];
for (let i = 0; i < 5; ++i) {
    results.push(await getDetails(param1,param2));
}
// Use `results
const getDetails = async (param1,param2) => {
    let list = await getAPIresults(param1)
    if(result.length === 5){
        //code to update a hook which causes render and displays the text in results array
    }
    return list;
}
,

您可能要使用Promise.all;这样也可以保留顺序:

Promise.all: Order of resolved values

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...