簡體   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