connect在捕获中间件的异常时,通过next携带error一个个中间件验证,直到错误处理中间件,而Koa中则是用Promise包装中间件,一旦中间件发生异常,那么会直接触发reject状态,直接在Promise的catch中处理就行。
上述就是connect中间件与Koa中间件的实现原理,现在在再看Koa中间件的这张执行流程图,应该没有什么疑问了吧?!
四、异常处理
对于同步代码,通过try/catch可以轻松的捕获异常,在connect中间件的异常捕获则是通过try/catch完成。
对于异步代码,try/catch则无法捕获,这时候一般可以构造Promise链,在最后的catch方法中捕获错误,Koa就是这样处理,并且在catch方法中发送error事件,以便开发者自定义异常处理逻辑。
this.app.emit('error', err, this);
前面也谈到Koa利用async/await语法带来同步方式书写异步代码的酸爽,另外也让错误处理更加自然:
// 也可以这样自定义错误处理 app.use(async (ctx, next) => { try { await next(); } catch (err) { ctx.status = err.status || 500 ctx.body = err } })
五、总结
相信看到这里,再回忆一下之前遇到的那些问题,你应该会有新的理解,并且再次使用Koa时会更加得心应手,这也是分析Koa源码的目的之一。