簡體   English   中英

等待異步遞歸函數完成,然后繼續執行下一行代碼

[英]Wait for async recursive function to complete before proceeding to next line of code

我正在嘗試等待遞歸函數完全完成,然后再繼續執行下一行代碼。 我正在使用PuppeteerJS在頁面上查找項目,如果該項目不存在,請在3秒鍾后重新加載頁面,然后重試。 在繼續之前,我需要完成此功能。 下面是我要實現的簡單代碼示例。

(async () => {
    await waitForThisToFinish() // Wait for this function no matter how long it takes
    console.log("Don't log until function has completed")
})()

async function waitForThisToFinish() {
    try {
        await findItemOnPage()  //function times out after 3 seconds
    }
    catch (ex) {
        // If Item is not found after 3 seconds an error is thrown.
        // Catch error and reload page to see if item has been loaded and look again.
        waitForThisToFinish() //recursive call
    }
}

當前,如果在第一次嘗試中未找到該項目,則會引發錯誤,並且遞歸成功啟動。 但是,代碼執行將繼續,並且不會等待功能成功完成。

有沒有辦法使“抓住”解決? 我是否需要從waitForThisToFinish()函數返回承諾? 遞歸將如何工作? 任何幫助,將不勝感激。

我建議您使用一個在成功時就中斷的循環,因為這樣就不會以任何方式積累資源(例如promise),並且如果需要,您可以無限次調用函數,而無需強調資源的使用。

async function waitForThisToFinish() {
    while (true) {
        try {
            let val = await findItemOnPage()
            // use break or return here to break out of the loop
            return val;
        } catch (ex) {
            console.log("still waiting and trying again")
        }
    }
}

此外,您還應該進行其他一些更改:

  1. 檢查實際錯誤,以確保其是可以通過重試(例如超時)解決的錯誤類型。 如果這是永久性錯誤,您將永遠重試。
  2. 在重試之前實施延遲,以避免在服務器端造成雪崩故障,並避免服務器因速率限制而阻塞。
  3. 在延遲中實施逐步退避。

由於您通常不希望在發生錯誤時編寫會錘打服務器的代碼(通過快速連續不斷地反復提出相同的請求),因為這可能會導致雪崩服務器故障,從而使小問題變成大問題很快,您可能應該實施一個延遲,然后再試一次;如果問題持續存在的時間越長,則延遲時間越長。

function delay(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}


async function waitForThisToFinish() {
    let waitTime = 100;
    while (true) {
        try {
            let val = await findItemOnPage()
            // use break or return here to break out of the loop
            return val;
        } catch (ex) {
            // Should also check if the actual error is one that is likely
            // temporary.  Otherwise, you may loop forever on a permanent error
            console.log("still waiting and trying again")
            // implement super simple backoff (there are much more elegant algorithms available)
            await delay(waitTime);
            waitTime += 300;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM