try catch 捕获异步的问题
场景:最近在做表单验证 发现了很多的form表单验证的时候很多都是采用的异步捕获?我依稀记得try catch 是捕获同步代码的错误机制,为什么可以捕获到异步的操作;以下是截取antDesign一段伪代码:
可以参考 下方的伪代码:
const result = () => { return new Promise((resolve, reject) => {
setTimeout(() => {
reject('我是错误')
}, 1000)
})
}
async function foo () {
try{
const m = await result()
}catch(error){
console.log(error,'9999')
}
};
foo()
问题:为什么可以捕获?这其中的原理是什么?是否只要带上await 的语法糖都是用try catch 进行捕获?
回答:
try catch
能捕获 async
函数中await的异步异常,是基于类es6 generator
生成器函数的调度机制。
除开async await是一些现代浏览器或者高版本node已经原生支持的不说。可以通过babel 将async await 编译成es5来透析它的ployfill实现。generator主要是两种调度类型,next
跟 throw
generator上有一个throw就是原声的throw方法
eg. 在https://babeljs.io/repl将以下代码转换,然后自行断点调试
function mockAsyncError(){ return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject("一个异步error")
},2000)
})
}
async function test(){
try{
console.log(1)
await mockAsyncError()
}catch(e){
console.log("e",e)
}
}
test()
// 转换为generator"use strict";
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function mockAsyncError() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject();
}, 2000);
});
}
function test() {
return _test.apply(this, arguments);
}
function _test() {
_test = _asyncToGenerator(function* () {
try {
console.log(1);
yield mockAsyncError();
} catch (e) {
consol.log("e", e);
}
});
return _test.apply(this, arguments);
}
test();
// es5版本"use strict";
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function mockAsyncError() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject();
}, 2000);
});
}
function test() {
return _test.apply(this, arguments);
}
function _test() {
_test = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
console.log(1);
_context.next = 4;
return mockAsyncError();
case 4:
_context.next = 9;
break;
case 6:
_context.prev = 6;
_context.t0 = _context["catch"](0);
consol.log("e", _context.t0);
case 9:
case "end":
return _context.stop();
}
}
}, _callee, null, [[0, 6]]);
}));
return _test.apply(this, arguments);
}
test();
回答:
就是语言本身的能力啊
在async function里try await的promise,就能把promise的异常捕获了
以上是 try catch 捕获异步的问题 的全部内容, 来源链接: utcz.com/p/935603.html