当前位置:网站首页>JS asynchronous error handling
JS asynchronous error handling
2022-07-05 08:42:00 【Carbonated goldfish.】
introduce
We all know try catch Unable to capture setTimeout Errors in asynchronous tasks , What is the reason . And asynchronous code in js Is particularly common , What should we do to compare ?
Situations that cannot be captured
function main() {
try {
setTimeout(() => {
throw new Error('async error')
}, 1000)
} catch(e) {
console.log(e, 'err')
console.log('continue...')
}
}
main();
In this code ,setTimeout The callback function of throws an error , Will not be in catch Capture in , It will cause the program to directly report errors and collapse .
So in the js in try catch It's not that you can rest easy by writing one . Should every function be written ?
Under what circumstances try catch Unable to capture error Well ?
1. Asynchronous task
The error in the callback function of the macro task cannot be caught
The chestnuts on it are slightly changed , Write a paragraph in the main task try catch, Then call the asynchronous task task,task Will throw an error after a second .
// Asynchronous task
var task = () => {
setTimeout(() => {
throw new Error('async error')
}, 1000)
}
// Main task
function main() {
try {
task();
} catch(e) {
console.log(e, 'err')
}
}
In this case main It's impossible catch error Of , This is related to the execution mechanism of the browser . Asynchronous tasks by eventloop Join the task queue , And take it out and put it on the stack (js The main process ) perform , And when task When taking out and executing , main The stack of has exited , That is to say The context has changed , therefore main Unable to capture task Error of .
Event callback , The request callback belongs to tasks, So the reason is the same .
eventloop Review can see this js Event loop mechanism in
Micro task (promise) The callback
// Return to one promise object
var promiseFetch = () =>
new Promise((reslove) => {
reslove();
})
function main() {
try {
// An error is thrown in the callback function
promiseFetch().then(() => {
throw new Error('err')
})
} catch(e) {
console.log(e, 'eeee');
}
}
promise The task of , That is to say then The callback function inside , Throwing an error also cannot catch. Because the micro task queue is in two task Empty between , therefore then When you push ,main Functions are also out of the stack .
2. It is not that the callback function cannot try catch
Many people may have a misunderstanding , Because most people can't catch The situation of , It all happens in the callback function , It is considered that the callback function cannot catch.
Not all right , Look at a common chestnut .
// Define a fn, Parameter is a function .
var fn = (cb: () => void) => {
cb();
};
function main() {
try {
// Pass in callback,fn Execution calls , And throw an error .
fn(() => {
throw new Error('123');
})
} catch(e) {
console.log('error');
}
}
main();
The result is, of course catch Of . because callback When it comes to execution , Follow main Still in the same event loop , That is, a eventloop tick. So the context hasn't changed , Mistakes can be catch Of . The root cause is synchronization code , No asynchronous tasks encountered .
promise Exception capture
Constructors
First look at two pieces of code :
function main1() {
try {
new Promise(() => {
throw new Error('promise1 error')
})
} catch(e) {
console.log(e.message);
}
}
function main2() {
try {
Promise.reject('promise2 error');
} catch(e) {
console.log(e.message);
}
}
The above two try catch Can't catch error, because promise Internal errors will not bubble out , But be promise Ate , Only through promise.catch Can capture , So use Promise Be sure to write catch ah .
Then let's take a look at using promise.catch Two pieces of code :
// reject
const p1 = new Promise((reslove, reject) => {
if(1) {
reject();
}
});
p1.catch((e) => console.log('p1 error'));
// throw new Error
const p2 = new Promise((reslove, reject) => {
if(1) {
throw new Error('p2 error')
}
});
p2.catch((e) => console.log('p2 error'));
promise Internal no matter reject perhaps throw new Error, Both can pass catch Callback capture .
Here we need to distinguish from the chestnuts in our first micro task ,promise The micro task of refers to then The callback , And here is Promise The first parameter passed in by the constructor ,new Promise It's synchronous .
then
that then How to catch the subsequent errors .
function main3() {
Promise.resolve(true).then(() => {
try {
throw new Error('then');
} catch(e) {
return e;
}
}).then(e => console.log(e.message));
}
Can only be inside a callback function catch error , And return the error message ,error Will be passed to the next then The callback .
use Promise Catch asynchronous errors
const p3 = () => new Promise((reslove, reject) => {
setTimeout(() => {
reject('async error');
})
});
function main3() {
p3().catch(e => console.log(e));
}
main3();
Operate asynchronously Promise packing , Through internal judgment , Mistake reject, Outside through promise.catch Capture .
async/await Exception capture
First, we simulate a function that fails a request fetchFailure,fetch Functions usually return a promise.
main The function is changed to async,catch To capture fetchFailure reject Errors thrown . Can you get it .
const fetchFailure = () => new Promise((resolve, reject) => {
setTimeout(() => {
// Simulation of the request
if(1) reject('fetch failure...');
})
})
async function main () {
try {
const res = await fetchFailure();
console.log(res, 'res');
} catch(e) {
console.log(e, 'e.message');
}
}
main();
Obviously .
Further more
async Function processing asynchronous process is a sharp weapon , But it will not go automatically catch error , We need to write try catch, If each function writes a , It's very troublesome , There are many asynchronous functions in the comparison business .
The first thing that comes to mind is to try catch, as well as catch After the logic is extracted .
const handle = async (fn: any) => {
try {
return await fn();
} catch(e) {
// do sth
console.log(e, 'e.messagee');
}
}
async function main () {
const res = await handle(fetchFailure);
console.log(res, 'res');
}
Write a package of higher-order functions fetchFailure, High order function multiplexing logic , Like here try catch, Then execute the passed in parameters - function that will do .
then , Plus the parameter passing of the callback function , And the return value follows first-error, towards node/go The grammar of . as follows :
const handleTryCatch = (fn: (...args: any[]) => Promise<{
}>) => async (...args: any[]) => {
try {
return [null, await fn(...args)];
} catch(e) {
console.log(e, 'e.messagee');
return [e];
}
}
async function main () {
const [err, res] = await handleTryCatch(fetchFailure)('');
if(err) {
console.log(err, 'err');
return;
}
console.log(res, 'res');
}
But there are still a few problems , One is catch The post logic , This piece does not support customization , Then, the return value should always be judged , Is there a error, You can also abstract it .
So we can find the function of higher order catch Write an article here , For example, adding some callback functions for error handling supports different logic , Then error handling in a project can be simply divided into several categories , Do different things , You can reuse the code as much as possible .
// 1. Third order function . The first incoming error handling handle, The second time is to introduce something to be modified async function , Finally, a new function.
const handleTryCatch = (handle: (e: Error) => void = errorHandle) =>
(fn: (...args: any[]) => Promise<{
}>) => async(...args: any[]) => {
try {
return [null, await fn(...args)];
} catch(e) {
return [handle(e)];
}
}
// 2. Define various error types
// We can format the error message , Become a style that can be handled in the code , For example, it contains error codes and error messages
class DbError extends Error {
public errmsg: string;
public errno: number;
constructor(msg: string, code: number) {
super(msg);
this.errmsg = msg || 'db_error_msg';
this.errno = code || 20010;
}
}
class ValidatedError extends Error {
public errmsg: string;
public errno: number;
constructor(msg: string, code: number) {
super(msg);
this.errmsg = msg || 'validated_error_msg';
this.errno = code || 20010;
}
}
// 3. The logic of error handling , This may be just one of them . Usually, error handling is divided according to functional requirements
// For example, the request fails (200 But the return value has an error message ), such as node Write in db Failure, etc .
const errorHandle = (e: Error) => {
// do something
if(e instanceof ValidatedError || e instanceof DbError) {
// do sth
return e;
}
return {
code: 101,
errmsg: 'unKnown'
};
}
const usualHandleTryCatch = handleTryCatch(errorHandle);
// The above code is reused by multiple modules , The actual business code may only need this .
async function main () {
const [error, res] = await usualHandleTryCatch(fetchFail)(false);
if(error) {
// because catch It's been intercepted , You can even add some general logic , There is no need to judge if error
console.log(error, 'error');
return;
}
console.log(res, 'res');
}
After solving the reuse problem of some wrong logic , That is, it can be encapsulated into different error processors .
边栏推荐
- MATLAB小技巧(28)模糊综合评价
- Halcon wood texture recognition
- Arduino+a4988 control stepper motor
- Sword finger offer 06 Print linked list from end to end
- [daily training -- Tencent selected 50] 557 Reverse word III in string
- Go dependency injection -- Google open source library wire
- Old Wang's esp8266 and old Wu's ws2818 light strip
- Bit operation related operations
- Guess riddles (8)
- Reasons for the insecurity of C language standard function scanf
猜你喜欢

猜谜语啦(142)

C# LINQ源码分析之Count

Mathematical modeling: factor analysis

Guess riddles (2)

Yolov4 target detection backbone

Apaas platform of TOP10 abroad

【三层架构】
![[nas1] (2021cvpr) attentivenas: improving neural architecture search via attentive sampling (unfinished)](/img/3b/c94b8466370f4461875c85b4f66860.png)
[nas1] (2021cvpr) attentivenas: improving neural architecture search via attentive sampling (unfinished)

Halcon color recognition_ fuses. hdev:classify fuses by color

猜谜语啦(2)
随机推荐
Halcon snap, get the area and position of coins
Matlab tips (28) fuzzy comprehensive evaluation
Hello everyone, welcome to my CSDN blog!
Example 006: Fibonacci series
Reasons for the insecurity of C language standard function scanf
Affected tree (tree DP)
Speech recognition learning summary
[matlab] matlab reads and writes Excel
Digital analog 2: integer programming
实例009:暂停一秒输出
猜谜语啦(9)
[牛客网刷题 Day4] JZ55 二叉树的深度
L298N module use
Go dependency injection -- Google open source library wire
实例004:这天第几天 输入某年某月某日,判断这一天是这一年的第几天?
Guess riddles (11)
Halcon blob analysis (ball.hdev)
Guess riddles (142)
Arduino operation stm32
【日常訓練--騰訊精選50】557. 反轉字符串中的單詞 III