【问题标题】:Async await in a for loopfor循环中的异步等待
【发布时间】:2018-02-09 02:24:29
【问题描述】:

假设我在一个 for 循环中有 2 个等待,我如何确保在执行第二个等待并因此再次循环之前完成第一个而不抛出错误。我尝试使用 Puppeteer 执行此操作,但即使未解决承诺,它也会继续循环...

for(var i = 0; i < 20; i++){
        console.log('loop started')
    await page1.goto('https://www.residentadvisor.net/dj.aspx?country=01').catch((err) =>{
        console.log('Page load fail : '+ err)
        if (err == 'Error: net::ERR_INTERNET_DISCONNECTED' || err == 'Error: net::ERR_NETWORK_CHANGED' || err == 'Error: net::ERR_NAME_NOT_RESOLVED'){
        let refreshIntervalId = setInterval(() =>{
           handleConnexionError(refreshIntervalId,page1)
        }, 5000) 
    }
    })
    console.log('Page loaded : ' + i)
    let teub = await page1.evaluate(() =>{
        return document.querySelector('a').innerText
    })
    console.log('Evaluate done : ' + teub )
    }



async function handleConnexionError(refreshIntervalId,page1){
    console.log('Retrying to connect')
    let errorHandle = true
    await page1.goto('https://www.residentadvisor.net/dj.aspx?country=01').catch(() => {
        errorHandle = false
    })
    if (errorHandle) {
        console.log('Succesfully Reconnected')
        clearInterval(refreshIntervalId)
        return true
    }
    else {
        console.log('Connection Fail Retrying in 10 sec ...')
    }
}

【问题讨论】:

  • 不,当 Promise 未解决时,它不会继续循环。第二部分将等到第一个 awaited 承诺完成。
  • 什么是handleConnexionError?展示下。此外,您可能希望在await page1.goto() 部分周围使用try/catch,而不是.catch()
  • @acdcjunior 我修好了!
  • 您可以为此使用 Bluebird Promise.reflect

标签: javascript asynchronous async-await puppeteer


【解决方案1】:

您可以创建一个新函数并在出错时递归调用它。

/**
 * checks if error matches
 * @param {Object} err thrown error
 * @return {Boolean}
 */
async function shouldRetry(err) {
    return [
        "Error: net::ERR_INTERNET_DISCONNECTED",
        "Error: net::ERR_NETWORK_CHANGED",
        "Error: net::ERR_NAME_NOT_RESOLVED"
    ].includes(err);
}

/**
 * Function to Re navigate endlessly on error
 * @param {Object} config
 * @param {string} config.page the page instance
 * @param {String} config.url url to browse
 * @param {Number} config.delay delay for retry
 * @return {Promise}
 */
async function navigateUrl({ page, url, delay }) {
    try {
        // wait for page load
        const response = await page.goto(url);
        return response;
    } catch (error) {
        if (shouldRetry(error)) {
            // use a delay promise or the built in waitFor function
            await page.waitFor(delay);
            // re navigate
            return navigateUrl({ page, url, delay });
        } else {
            // throw on other errors
            throw new Error(error);
        }
    }
}

// now you can use them however you want
await navigateUrl({ page, 'http://example.com', 2000 });
await page.evaluate(() =>{
    return document.querySelector('a').innerText
});

最好能把东西分开,更容易编写和维护。

【讨论】:

    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多