如何捕获外部 try/catch 块上的异步回调函数的错误
How to catch an error on a async callback function on outer try/catch block
好的,
所以我正在使用 puppeteer 框架,并且我有一个与网页交互的异步函数。
该函数在等待页面流量空闲时点击和选择网页元素。
此功能大部分时间有效,但有时会停止。
我希望能够设置超时,这样如果该函数花费的时间超过一定时间,它就会抛出一个错误,我可以再次 运行 它。
到目前为止,我似乎无法让它工作,因为我无法使用外部函数获得传递给 setTimeOut()
到 'interact' 的回调函数。
我的代码如下所示:
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
}
}
我还尝试按照 this post 将 setTimeOut
函数包装在 Promise
中,并使用 .then().catch()
回调尝试捕获错误但无济于事.
如果这是一个愚蠢的问题,我们深表歉意,感谢您的帮助。
尝试将 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
}
}
您 运行 遇到的问题本质上是 setTimeout()
中抛出的错误与您的函数流无关,因此无法在那里捕获。您基本上可以将计时器的回调函数视为“分离”函数:来自父作用域的变量仍然可用,但您不能 return
直接向父作用域等
要解决此问题,您有几种选择,Promise.race()
是一种可能的解决方案。这个想法是首先制作一个超时的异步版本:
const rejectAfter = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => reject(), timeout);
});
};
然后将您的业务逻辑提取到单独的异步函数中 a-la:
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
}
}
好的,
所以我正在使用 puppeteer 框架,并且我有一个与网页交互的异步函数。 该函数在等待页面流量空闲时点击和选择网页元素。 此功能大部分时间有效,但有时会停止。
我希望能够设置超时,这样如果该函数花费的时间超过一定时间,它就会抛出一个错误,我可以再次 运行 它。
到目前为止,我似乎无法让它工作,因为我无法使用外部函数获得传递给 setTimeOut()
到 'interact' 的回调函数。
我的代码如下所示:
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
}
}
我还尝试按照 this post 将 setTimeOut
函数包装在 Promise
中,并使用 .then().catch()
回调尝试捕获错误但无济于事.
如果这是一个愚蠢的问题,我们深表歉意,感谢您的帮助。
尝试将 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
}
}
您 运行 遇到的问题本质上是 setTimeout()
中抛出的错误与您的函数流无关,因此无法在那里捕获。您基本上可以将计时器的回调函数视为“分离”函数:来自父作用域的变量仍然可用,但您不能 return
直接向父作用域等
要解决此问题,您有几种选择,Promise.race()
是一种可能的解决方案。这个想法是首先制作一个超时的异步版本:
const rejectAfter = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => reject(), timeout);
});
};
然后将您的业务逻辑提取到单独的异步函数中 a-la:
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
}
}