行,
所以我正在使用 puppeteer 框架,并且我有一個與網頁互動的異步函式。該函式在等待頁面流量空閑時點擊并選擇網頁的元素。此功能大部分時間都有效,但有時會停止。
我希望能夠設定超時,以便如果函式花費的時間超過一定時間,它會引發錯誤,我可以再次運行它。到目前為止,我似乎無法讓它作業,因為我無法獲得傳遞給與setTimeOut()外部函式“互動”的回呼函式。
我的代碼如下所示:
const scrap_webtite = async page => {
/* scrap the site */
try{ // catch all
// set timeout
let timed_out_ID = setTimeout(()=> throw "timeOut", 1000);
// run the async
let el = await sometimes_stalls_function(page);
// if function ran finished correcly
clearTimeout(timed_out_ID);
// save el
save_el(el);
}
}catch(e){
console.error("Something went wrong!", e);
// this makes the function run again
// here is where I want to ideally catch the timeout error
return false
}
}
我還嘗試按照這篇文章setTimeOut將函式包裝在一個中,并使用回呼來嘗試捕獲錯誤,但無濟于事。Promise.then().catch()
抱歉,如果這是一個愚蠢的問題,謝謝您的幫助。
uj5u.com熱心網友回復:
您遇到的問題本質上是拋出的錯誤setTimeout()與您的功能流程無關,因此無法在此處捕獲。您基本上可以將計時器的回呼函式視為“分離”函式:來自父范圍的變數仍然可用,但您不能return直接為父范圍賦值等。
要解決此問題,您有幾個選擇,Promise.race()這是一種可能的解決方案。這個想法是首先制作一個異步版本的超時:
const rejectAfter = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => reject(), timeout);
});
};
然后將您的業務邏輯提取到一個單獨的異步函式中:
const doTheThing = async () => {
// TODO: Implement
};
最后,在您的抓取功能中,使用Promise.race()先完成兩者中的任何一個的結果:
const scrape = async (page) => {
try {
const el = await Promise.race([
rejectAfter(1000),
doTheThing()
]);
} catch(error) {
// TODO: Handle error
}
}
uj5u.com熱心網友回復:
嘗試將try塊中的所有內容都變成一個承諾
const scrap_webtite = async page => {
/* scrap the site */
try{ // catch all
return await new Promise(async(r,j)=>{
// set timeout
let timed_out_ID = setTimeout(()=>j("timeOut"),1000);
// run the async
let el = await sometimes_stalls_function(page);
// if function ran finished correcly
clearTimeout(timed_out_ID);
// save el
r(save_el(el));
})
}catch(e){
console.error("Something went wrong!", e);
// this makes the function run again
// here is where I want to ideally catch the timeout error
return false
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/463965.html
標籤:javascript 异步等待 傀儡师 设置超时 es6-承诺
