繁体   English   中英

javascript 中的异步/等待 for 循环

[英]Async/Await in javascript for loop

我有一个反应组件,它在组件的安装上运行这个 function。

 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,3,4,5]这意味着上面的代码没有运行异步任务按他们到达的顺序。 所以有人可以帮我解决这个问题,我希望代码按照到达的顺序发出异步请求。

您需要再次使用await关键字来等待循环的每次迭代完成,然后再进入下一轮。

await getDetails(param1,param2)

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

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 function:

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拒绝 promise 来处理传播给它的任何错误):

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));
}
const results = await Promise.all(promises)
// `results` is an array of the results, in the same order as the
// array of promises

如果您需要它们不重叠而是一个接一个地运行,最好的办法是使用async function 进行循环。

如果您不能getListOfItems async function:

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拒绝 promise 来处理传播给它的任何错误):

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:解析值的顺序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM