先看例子:
Promise.resolve("new").then((value)=>{
Promise.resolve("other").then(()=>{
throw new Error("error");
})
}).catch((reason)=>{
console.log(reason);
})
这个代码运行时,会捕获错误吗?答案是不会。
Promise.resolve会返回一个新的promise,相当于new一个promise对象。
内层的promise确实是抛出了错误,但它没有return给外层promise,此时相当于return undefined,这样就不是错误,外层也就没法捕获。
then方法返回的都是promise,而且promise对象有then方法,所以then可以链式调用。
可以在then方法中new Promise并return,之后的then方法都是基于这个新的promise。
修复:
补上return就可以捕获错误了
Promise.resolve("new").then((value)=>{
return Promise.resolve("other").then(()=>{
throw new Error("error");
})
}).catch((reason)=>{
console.log(reason);
})
换个形式:
封装成fn函数导致继续return undefined,无法捕获。此时要想捕获换成return或者async、await形式
Promise.resolve(fn()).catch(reason=>{
console.log(reason);
})
function fn(){
Promise.reject("error")
}
但如果直接指向代码,不经过fn方法,则可以捕获:
Promise.resolve(Promise.reject("error")).catch(reason=>{
console.log(reason);
})
再看一个例子:
function dispatch(){
try {
return Promise.resolve( fn());
} catch (error) {
return Promise.reject("err");
}
}
function fn(){
Promise.reject("err");
}
dispatch().catch(reason=>{
console.log(reason);
})
执行fn方法,同样捕获不到错误,因为没有return promise,导致return undefined ,也就不是错误,无法捕获。
解决办法之一:
加上return语句
function dispatch(){
try {
return Promise.resolve( fn());
} catch (error) {
return Promise.reject("err");
}
}
function fn(){
return Promise.reject("err");
}
dispatch().catch(reason=>{
console.log(reason);
})
解决办法之二:
使用async 和await方法
function dispatch(){
try {
return Promise.resolve( fn());
} catch (error) {
return Promise.reject("err");
}
}
async function fn(){
await Promise.reject("err");
}
dispatch().catch(reason=>{
console.log(reason);
})
koa2 web框架是基于中间件模型设计,使用了async/await方法。如果按照async和await的写法写中间件函数,koa自带错误捕获,一般是不会出现问题的。
如果终端确实出现了UnhandledPromiseRejectionWarning,此时需要检查async和await是否书写正确,还有return方法。通过上面提到的两种方案,二选一即可。当然是推荐async和await了。
koa2洋葱模型
参考学习链接:https://github.com/niexq/koaComposeTest
koa2洋葱模型关键就靠compose方法,compose中文是组合的意思,就是将平行函数,组合成回调金字塔
// 我们定义的中间件
fn1(ctx, next);
fn2(ctx, next);
fn3(ctx);
// 组合成
fn1(ctx, () => {
fn2(ctx, () => {
fn3(ctx);
})
});
上述代码引用自:https://www.52cik.com/2018/05/27/koa-error.html