try catch 捕获异步的问题

场景:最近在做表单验证 发现了很多的form表单验证的时候很多都是采用的异步捕获?我依稀记得try catch 是捕获同步代码的错误机制,为什么可以捕获到异步的操作;以下是截取antDesign一段伪代码:
try catch 捕获异步的问题

可以参考 下方的伪代码:

  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主要是两种调度类型,nextthrow 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

回到顶部