如何优雅的在node koa 日志处理中处理错误

在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
是这样的, 我在写登录验证的时候遇到了一个这样的问题。我在store方法中进行了登录验证。其中 StoreLoginPost类主要是进行了各种表单验证,
namespace App\Http\R
use Illuminate\Foundation\Http\FormR
class StoreLoginPost extends FormRequest
* Determine if the user is authorized to make this request.
* @return bool
public function authorize()
* 验证规则
* @return array
public function rules()
'account' =& 'required',
'password' =& 'required|min:6',
* 提示消息处理
* @return array
public function messages()
'account.required' =& '用户名不能为空',
'password.required' =& '密码不能为空',
'password.min' =& '密码不能少于六位',
当表单提交的时候,如果不符合我要求的规则会返回一个Illuminate\Support\MessageBag $errors对象,
而我则从$errors对象中获取错误信息以提示用户表单的不符合规则,这是表单验证错误的,
如果数据库中查询不到用户,如图一中红色框出来的部分,我应该怎么优雅的处理这个错误,难道只能用flash session? 闪存固好,但是我觉得有一些别扭, 正如图二的三个箭头示意,错误既存在$errors中也存在session中,是否能统一的处理, 或者有更好的处理方法, 望指教。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
可以在FormRequest这个子类里面添加rule, 就是判断密码对不对的.
如果这样, 那接收到这个$request时, 可以确定用户名密码验证成功了.
如果验证失败, 由验证框架返回到上一步.
使用 -&withErrors(['msg' =& '验证失败']), 可以在模板里统一使用$errors变量.
其实这个本质上还是-&flash().
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:1650人阅读
nodejs(62)
当传输文件过大时候,koa-body 报告413 too large
解决办法:添加如下配置
var koaBody = require('koa-body')({
"formLimit":"5mb",
"jsonLimit":"5mb",
"textLimit":"5mb"
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1202974次
积分:13796
积分:13796
排名:第986名
原创:381篇
转载:199篇
译文:12篇
评论:45条
(2)(27)(2)(11)(15)(2)(3)(8)(17)(16)(29)(7)(12)(23)(28)(8)(17)(28)(34)(2)(3)(10)(12)(13)(9)(4)(18)(9)(2)(13)(30)(15)(12)(24)(3)(14)(18)(5)(3)(1)(1)(5)(5)(3)(1)(8)(2)(1)(2)(1)(7)(7)(3)(5)(7)(10)(2)(2)(2)(3)(4)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'如何使用koa2+es6/7打造高质量Restful API - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"contributes":[{"sourceColumn":{"lastUpdated":,"description":"分享一些自己写的关于react、nodejs、docker等全栈开发相关技术文章","permission":"COLUMN_PUBLIC","memberId":,"contributePermission":"COLUMN_PRIVATE","translatedCommentPermission":"all","canManage":true,"intro":"最前沿的全栈开发技术分享","urlToken":"sessionboy","id":32732,"imagePath":"v2-d003f025c576ef8f4248c6bddc0964a0.jpg","slug":"sessionboy","applyReason":"0","name":"sessionboy全栈开发","title":"sessionboy全栈开发","url":"/sessionboy","commentPermission":"COLUMN_ALL_CAN_COMMENT","canPost":true,"created":,"state":"COLUMN_NORMAL","followers":264,"avatar":{"id":"v2-d003f025c576ef8f4248c6bddc0964a0","template":"/{id}_{size}.jpg"},"activateAuthorRequested":false,"following":false,"imageUrl":"/v2-d003f025c576ef8f4248c6bddc0964a0_l.jpg","articlesCount":7},"state":"accepted","targetPost":{"titleImage":"/v2-ffadc267a79b0e35ec98c_r.jpg","lastUpdated":,"imagePath":"v2-ffadc267a79b0e35ec98c.jpg","permission":"ARTICLE_PUBLIC","topics":[,166758],"summary":"0. 前言如今nodejs变得越来越火热,采用nodejs实现前后端分离架构已被多数大公司所采用。在过去,使用nodejs大家首先想到的是大神写的,而发展到如今,更轻量,性能更好的已然成为主流,它同样出自大神手笔,如今版本已更新到了koa2,不仅…","copyPermission":"ARTICLE_COPYABLE","translatedCommentPermission":"all","likes":0,"origAuthorId":0,"publishedTime":"T22:52:32+08:00","sourceUrl":"","urlToken":,"id":2673592,"withContent":false,"slug":,"bigTitleImage":false,"title":"如何使用koa2+es6/7打造高质量Restful API","url":"/p/","commentPermission":"ARTICLE_ALL_CAN_COMMENT","snapshotUrl":"","created":,"comments":0,"columnId":0,"content":"","parentId":0,"state":"ARTICLE_PUBLISHED","imageUrl":"/v2-ffadc267a79b0e35ec98c_r.jpg","author":{"bio":"全栈工程师","isFollowing":false,"hash":"a68812cae4a25e23afd99e8c2fc25307","uid":915600,"isOrg":false,"slug":"su-mu-hua-62","isFollowed":false,"description":"全栈工程师
\ngithub: /sessionboy
\n个人站点:/
sessionboy
\n知乎专栏: /sessionboy","name":"sessionboy","profileUrl":"/people/su-mu-hua-62","avatar":{"id":"v2-20d0f03987db6dfebb6e3e68c268612f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"memberId":,"excerptTitle":"","voteType":"ARTICLE_VOTE_CLEAR"},"id":606492}],"title":"如何使用koa2+es6/7打造高质量Restful API","author":"su-mu-hua-62","content":"0. 前言如今nodejs变得越来越火热,采用nodejs实现前后端分离架构已被多数大公司所采用。在过去,使用nodejs大家首先想到的是大神写的,而发展到如今,更轻量,性能更好的已然成为主流,它同样出自大神手笔,如今版本已更新到了koa2,不仅性能优异,它还支持async/await,堪称回调地狱的终结者下面,我们来探讨下,如何使用koa2+es6/7来打造高质量的Restful风格API。刨根问底,篇幅略长,精华在后面,需要耐心看。1. 两种模式一种是耦合模式,即接口层和逻辑层都由一个函数来处理完成。另一种是分离模式,即接口层和逻辑层是分开的。下面我们先来说第一种。耦合模式先举个粟子,以express为例:# /server/user/login.js
用户登录\n\nconst express = require('express');\nconst router = express.Router();\n\n router.post('/api/user/login',function(req,res){\n\n
// 逻辑层\n\n })\n\n# /server/user/register.js
用户注册\n\nconst express = require('express');\nconst router = express.Router();\n\n router.post('/api/user/register',function(req,res){\n\n
// 逻辑层\n\n })\n\n# /server/user/put.js
更改用户资料\n\nconst express = require('express');\nconst router = express.Router();\n\n router.post('/api/user/put',function(req,res){\n\n
// 逻辑层\n\n })\n这种在过去很常见,相信很多人都写过,我也不例外。但并不推荐。首先,一个应用的api通常会很多,如果应用够复杂,那意味着你的api可能要处理非常多的逻辑。而为了应付这些需求,你不得不建立很多的文件,甚至困扰于如何划分和组织好这些文件。其次,后期并不好维护,当api过多,过于繁杂时,文件深层嵌套,也许你找一个api文件都费神费力。分离模式同样先来个粟子:# /server/router.js\n\nconst express = require('express');\nconst router = express.Router();\n\n router.post('/api/user/login',require('../controllers/users/login'))
// 用户登录\n\n
.post('/api/user/register',require('../controllers/users/register'))
// 用户注册
.put('/api/user/put',require('../controllers/users/put')
// 更改用户资料\n\n
.delete('/api/user/deluser',require('../controllers/users/deluser'))
// 删除用户\n
……\n很显然,这种api已将接口层和逻辑层分离了,接口层由一个router.js文件来统一定义,而每个接口的逻辑层则由单独的文件来处理,并按不同功能模块用不同文件夹来组织这些逻辑文件。那么,这样做有什么好处呢?首先,很直观,整个结构很清晰,一目了然其次,只需要你专注于处理逻辑再者,api集中在router.js文件定义,同事更容易看懂你的代码结构,或者知道你增改了哪些api等等,这很方便于多人协同开发,在大型开发中尤为重要很显然,分离模式优于耦合模式。2. 如何更好地组织逻辑层经过上面的分析之后,我们选择更优的分离模式, 它只需要你关注逻辑层。但是,以上面分离模式的例子为例,每一个接口仍然需要单独一个js文件来处理它的逻辑层,并且需要用很多不同文件夹来组织它们,假如应用足够大,有几十甚至上百个api,那意味着很有可能你的js逻辑文件也达几十乃至上百个,而用来划分和组织这些js文件的文件夹也不在少数。这就造成了过于臃肿,难以维护的毛病。那么,有没有可能,一个功能模块只需要一个js文件来处理它们的所有逻辑层,并更具可维护性呢?打个比方,现在有一个博客站点,我仅使用一个user.js文件来处理用户模块所有api的逻辑层,包括注册,登录,修改,删除,密码重置等等,另外用一个article.js文件来处理文章模块所有api的逻辑层,包括发布,修改,获取详情,点赞,评论,删除等等。如果可以做到这样,那就意味着代码量大大减少,且可维护性更高。而要做到这步,我们需要解决两个问题,一个是异步回调,因为异步回调使我们增加了很多代码量,逻辑复杂,二是如何批量定义和导出大量api的逻辑层方法。首先,我们先来解决异步回调这个问题,下面将会展开讲解。为了减少篇幅,下面只做简要的浅析。express 时代我们先来回顾一下历史。鉴于nodejs的回调机制,很多异步操作都需要回调来完成,如果你的逻辑足够复杂,很可能就会陷进回调地狱,下面是一个简单的例子:……\nfs.readFile('/etc/password', function(err, data){\n
// do something\n
fs.readFile('xxxx', function(err, data){\n
//do something\n
fs.readFile('xxxxx', function(err, data){\n
// do something\n
})\n})\n……\n同样,express也不例外,常常会让你深陷回调地狱。通常一个api需要写大量的代码来完成,此时为了更好地开发和维护,你不得不每个api都单独一个js文件来处理。为了解决异步回调这个大问题,js生态出现了很多解决方案,其中比较好的两个——promise,async。promise, async时代首先说说。这曾是一个非常优秀的第三方模块,它基于回调机制来实现,是处理异步回调很好的解决方案,如今github上已超两万多颗星。提供两个非常好的处理异步的方法,分别是串行执行的waterfall,以及并行执行的parallel。下面来个粟子:# waterfall 按顺序执行,执行完一个,传递给下一个,最终结果返回给最后的回调函数\n\nasync.waterfall([\n
function(callback){\n
callback(null, 'one', 'two');\n
function(arg1, arg2, callback){\n
// arg1 now equals 'one' and arg2 now equals 'two'\n
callback(null, 'three');\n
function(arg1, callback){\n
// arg1 now equals 'three'\n
callback(null, 'done');\n
}\n], function (err, result) {\n
// result now equals 'done'\n
console.log(result);\n});\n\n# parallel 并行执行,即同时执行\n\nasync.parallel([\n
function(callback){\n
callback(null, 'one');\n
function(callback){\n
callback(null, 'two');\n
}\n],\nfunction(err, results){\n
// 最终处理\n});\n很显然,这很大程度上避免了回调地狱,并且有一个完整的控制流,使你可以很好的组织代码。接下来说说promise作为一名合格的前端,你有必要对有所了解,可以参考阮一峰写的es6入门之。首先,promise是es6的特性之一,实际是可用来传递异步操作流的对象。promise提供三种状态,Pending(进行中),Resolved(已解决),Rejected(已失败)。promise提供两个方法,resolve()和reject(),可用于处理最终结果。promise还提供一个then方法,用于异步处理过程,这是一个控制流方法,可以不停地执行下去,直到得到你想要的结果。promise还提供了catch方法,用于捕获和处理异步处理过程中出现的异常。下面来举个粟子:var promise = new Promise(function(resolve, reject) {\n\n
// 一些异步逻辑,比如ajax, setTimeout等\n\n
if (/* 异步操作成功 */){\n
resolve(value);
// 成功则返回结果\n
} else {\n
reject(error);
// 失败则返回错误\n
}\n}).then(function(value){\n
// 不是想要的结果,继续往下执行\n}).then(function(value){\n
// 不是想要的结果,继续往下执行\n}).then\n……\n\n}).then(function(value){\n
// 是最终想要的结果\n}).catch(function(err){\n\
// 如果有异常则抛出\n\n})\n那么,能不能同时执行多个promise实例呢?可以的,promise.all()方法可以帮到你。不得不说,promise是解决异步回调的一大进步,是一个非常优秀的解决方案。而由于promise的强大,生态圈出现了很多基于promise的优秀模块, 比如, 等等。然而,promise并非终点,它只是弱化了回调地狱,并不能真正消除回调。使用promise仍然要处理很多复杂的逻辑,以及写很多的逻辑代码而要消除回调,意味着要实现以同步的方式来写异步编程。那么如何来实现?此时舞台再次交给大神,因为他写了个,利用协程机制,实现以同步的方式来写异步编程。不得不膜拜下大神。generator 时代关于generator的相关知识,可参考阮一峰老师写的es6入门之。和promise一样,generator同样是es6的新特性,但它并非为解决回调而存在的,只是它恰好拥有这个能力,而大神看到这种可能,于是他利用generator封装了。并基于,他又创造了个更轻量,性能更好的web框架。自此,koa1终于诞生了!它迎合了es6和co,koa1和express相比,有非常大的进步,其中之一就是它很大程度上真正地解决了异步回调问题,真正意义上实现同步方式来写异步编程。再就是,koa1更轻量,性能比express更为优异。koa1实现同步写异步的关键点就是。那么,是如何实现同步写异步的呢?下面继续来个举个粟子:# 正常的异步回调\nvar request = require('request');\nvar a = {};\nvar b = {};\nrequest('', function (error, response, body) {\n
if (!error && response.statusCode == 200) {\n
a.response =\n
a.body =\n
request('', function (error, response, body) {\n
if (!error && response.statusCode == 200) {\n
b.response =\n
b.body =\n
}\n});\n\n\n# co异步处理\n\nco(function *(){\n
var a = yield request('');
// 以同步的方式,直接拿到异步结果,并往下执行\n
var b = yield request('');\n
console.log(a[0].statusCode);\n
console.log(b[0].statusCode);\n})()\n看完这个粟子,是不是十分的激动呢?我们再来看看,基于co的koa1是如何处理异步的, 同样举个粟子:# 发布文章接口\n\nconst parse = require('co-body');\nconst mongoose = require('mongoose');\nconst Post = mongoose.model('Post');\n\n// 发布文章\nexports.create = function *() {
// 使用 *表示这是一个gentator函数\n
let post = new Post(this.req.body.post);\\n\n
post.set('user_id', this.user.id);\n\n
if (yield post.save()) {
// yield直接获取异步执行的结果\n
this.redirect('/admin/posts');\n
} else {\n
tags = yield Tag.findAll();\n
this.body = yield render('post/new', { post: post.toJSON(), tags: tags.toJSON() });
// yield直接获取异步执行的结果\n
}\n}\n想象一下,这个例子如果使用express来做会是怎样呢?相信你心中有数,很无情地抛弃了express,express哭晕厕所?。下面开始回归正题。我们来探讨下,如何使用更好的组织结构,更少的代码量来实现大量api的逻辑层3, 探讨一,koa1的实现经过前面的诸多讲述了解到,异步回调这一大难题,到了koa1才真正意义上的得以解决,准确来说是generator的功劳。以同步的方式处理异步回调,这才是我们想要的结果,意味着我们可以用很少的代码量来实现api的逻辑层。解决了异步回调后,此时我们考虑另一个问题,如何集中处理,暴露大量api逻辑层?此时,时代进步的利器——es6,排上用场了。使用es6这里主要使用es6的几个新特效,export, import等等。下面,我们举个粟子来讲述:首先是api接口层# /server/router.js
// 组织api的接口层\n\n const router = require('koa-router')();
// koa1.x\n const userctrl = require('../controllers/users/userctrl');
// 引用用户模块逻辑层\n const
articlectrl = require('../controllers/articles/articlectrl');
// 引用文章模块逻辑层\n\n router\n
用户模块api\n
.post('/api/user/login',userctrl.login)
// 用户登录\n\n
.post('/api/user/register',userctrl.register)
// 用户注册
.put('/api/user/put',userctrl.put)
// 更改用户资料\n\n
.put('/api/user/resetpwd',userctrl.resetpwd)
// 重置用户密码\n\n
.delete('/api/user/deluser',resetpwd.deluser)
// 删除用户\n\n
// 文章模块api\n
.post('/api/article/create',articlectrl.create)
// 发布文章\n\n
.get('/api/article/detail',articlectrl.detail)
// 获取文章详情
.put('/api/article/put',articlectrl.put)
// 编辑文章\n\n
.delete('/api/article/del',articlectrl.del)
// 删除文章\n\n
.post('/api/article/praise',articlectrl.praise)
// 点赞文章\n\n
.post('/api/article/comments',ments)
// 发布评论\n\n
.delete('/api/article/del_comments',articlectrl.del_comments);
// 删除评论\n\n
e\n不知注意到没,用户模块和文章模块都分别只引入了一个文件,分别是userctrl.js和articlectrl.js,所有用户和文章模块相关的api逻辑层都集中在这两个文件中处理。如何做的呢? 请看下面的粟子:用户模块# /controllers/users/userctrl.js\n\n// 用户登录\nexports.login = function *(){\n
// yield ....\n}\n\n// 用户注册\nexports.register = function *(){\n
// yield ....\n}\n\n// 更改用户资料\nexports.put = function *(){\n
// yield ....\n}\n\n// 重置用户密码\nexports.resetpwd = function *(){\n
// yield ....\n}\n\n// 用户登录\nexports.deluser = function *(){\n
// yield ....\n}\n文章模块# /controllers/articles/articlectrl.js\n\n// 发布文章\nexports.create = function *(){\n
// yield ....\n}\n\n// 获取文章详情\nexports.detail = function *(){\n
// yield ....\n}\n\n// 编辑文章\nexports.put = function *(){\n
// yield ....\n}\n\n// 删除文章\nexports.del = function *(){\n
// yield ....\n}\n\n// 点赞文章\nexports.praise = function *(){\n
// yield ....\n}\n\n// 发布评论\ments = function *(){\n
// yield ....\n}\n\n// 删除评论\nexports.del_comments = function *(){\n
// yield ....\n}\n到了这一步,api接口层和逻辑层都已处理完毕。这里有个小问题,使用koa,意味着你需要使用try/catch去捕获内部错误,但如果每个api都try/catch一遍,那是极其繁琐的,也会占用不少代码量和空间对于这个问题,我们可以把try/catch封装成一个中间件来处理,只需要把这个中间放在路由之前执行即可。对此,可以参考阿里云栖里的这篇文章——至此,一个基于koa1+es6的Restful API打造完成。然而,这仍不是终点。4. co的末日,也是koa1的末日co/koa1这么厉害,实现了promise,async都解决不了的同步写异步,为什么会是末日呢?co/koa1并不是不好,而是有比它更好的,从而淹没了他们的光芒,所谓壮士一去不复返,垂泪三千尺?。是什么抢走了co/koa1的光芒?你应该猜到了,那就是、async/await来势汹汹,它有个代号,叫——终结者。别误会,不是那个酷酷的美国大叔。async/await并非第三方实现,而是原生javascript的实现,也就是说它不是bluebird,q,async那一流,将来它是要进入w3c标准的,官方的解决方案。 准确地说,它才是正统皇帝,generator只是代皇帝,bluebird,q,async之类的则只是江湖侠客。为此,自nodejs发布到7.x以后,TJ 大神推出了koa2,内置co包,直接支持async/await。并将会在koa3中完全移除对generators的支持。async/await非常新,它并不属于es6,而是属于es7。和generator一样,它实现了同步写异步,终结异步回调。而async/await具有非常大的优势,首先它本身是generator语法糖,自带执行器,更具语义化,适用性更广。其次,它并不需要像co这样的第三方实现,而是原生支持的。那么,使用async/await是怎样的体验呢?以我的开源博客源码为例,下面来个粟子:// 查询二级文章分类\n
static async get_category(ctx) {
// async声明这是一个async函数\n
const data = await CategoryModel.find();
// await 获取异步结果\n
if(!data) return ctx.error({msg: '暂无数据'});\n
return ctx.success({ data });\n
// 查询分类菜单\n
static async getmenu_category(ctx) {\n
const data = await CategoryModel.find({}).populate('cate_parent');\n
if(!data) return ctx.error({msg: '获取菜单失败!'});\n
return ctx.success({ data });\n
}\n5. 探讨二,koa2+es6/7的实现直接奔入最终主题。前面讲了koa1+es6实现Restful API的打造,可它并非是最优解。真正的最优方案是koa2+async/await+class的实现。这里为什么提到class呢?class是es6版的面向对象的实现,是的,你没有看错,你曾经所熟悉的oop可以玩起来了。可是,这里为什么需要用到它?因为,class+async/await的结合,可以使你更好的组织api的逻辑层,语义更清晰,结构更清晰,代码量更少更轻,更容易维护。至此,你不再需要export每个接口逻辑了。另一个优点,它同样具有很好的性能。下面来个真实的粟子,以我的开源博客源码为例:首先是接口层:# /server/router.js
// 组织api的接口层\n\n const router = require('koa-router')(); \n const userctrl = require('../controllers/users/UserController');
// 引入用户模块逻辑层\n\n router\n
用户模块api\n
.post('/api/user/login',userctrl.login)
// 用户登录\n
.post('/api/user/register',userctrl.register)
// 用户注册
.get('/api/user/logout',userctrl.logout)
// 用户退出
.put('/api/user/put',userctrl.put)
// 更改用户资料\n
.put('/api/user/resetpwd',userctrl.resetpwd)
// 重置用户密码\n
.delete('/api/user/deluser',resetpwd.deluser)
// 删除用户\n
……\n然后是逻辑层# /server/users/UserController.js
\n\nimport mongoose from 'mongoose';\nimport md5 from 'md5';\nconst UserModel = mongoose.model('User');\n\nclass UserController {\n\n
// 用户注册\n
async register(ctx) {\n
// await ……\n
// 用户登录\n
async login(ctx) {\n
// await ……\n
// 用户退出\n
async logout(ctx) {\n
// await ……\n
// 更新用户资料\n
async put(ctx) {\n
// await ……\n
// 删除用户\n
async deluser(ctx) {\n
// await ……\n
}\n\n // 重置密码\n
async resetpwd(ctx) {\n
// await ……\n
……\n\n}\nexport default new UserController();\n是不是更清晰,更有结构性了呢?你甚至还可以用extends(继承)来实现更复杂的api。但是,不知你有没有注意到一个细节,上面的例子用了new实例化。实例化,意味着会消耗一定内存,消耗性能。虽然在后端这是种消耗不会很大。但是作为一名优秀的程序员,我们尽量追求极致。需要明白的一点是,通常我们的api不会复杂到大量使用oop的知识,比如大量地使用原型,继承来实现复杂的实例,并没有,至少后端js逻辑不会是前端那般复杂。其次,我们的需求很简单,只需要能够批量定义和导出众多api的逻辑层方法即可。既然如此,为什么不用静态方法呢?是的,static来了。es6的class中,可用static来定义静态方法,甚至可以定义静态属性(es7才实现)。静态方法并不需要实例化就可以访问,也就意味着,使用static,你不需要new,你可以减少内存的损耗。下面我们改造一下上面逻辑层的例子:class UserController {\n\n
// 用户注册\n
static async register(ctx) {\n
// await ……\n
// 用户登录\n
static async login(ctx) {\n
// await ……\n
// 用户退出\n
static async logout(ctx) {\n
// await ……\n
// 更新用户资料\n
static async put(ctx) {\n
// await ……\n
// 删除用户\n
static async deluser(ctx) {\n
// await ……\n
}\n\n // 重置密码\n
static async resetpwd(ctx) {\n
// await ……\n
……\n\nexport default UserC\n\n}\n是不是感觉高大上了很多?另外,还有两点我们可以优化的。第一点是,避免在每个接口逻辑层中使用try/catch,而是封装一个try/catch中间件来处理它们,这样可以减少代码量,工作量,以及减少空间的占用。第二点是,把一些公共方法抽离出来,同样用class来组织它们,使用也很简单,你可以单独引进,也可以使用extends来继承公共方法的class类,以访问父类方法的方式来获取它们。至此,一个基于koa2+es6/7打造的高质量Restful API终于完成。总结如果你正准备学nodejs,除了原生node以外,你可以直接学习和使用koa2。如果你习惯于express或koa1,也建议迁移到koa2async/await以及众多es6/7特性的出现,是对nodejs负担的一种释放,你可以很好地利用好它们来提高你的编码效率和质量。本文首发于我的个人站点:具体实践案例可参考我的开源博客的后端。","updated":"T14:52:32.000Z","canComment":false,"commentPermission":"anyone","commentCount":22,"collapsedCount":0,"likeCount":96,"state":"published","isLiked":false,"slug":"","lastestTipjarors":[{"isFollowed":false,"name":"viot1026","headline":"","avatarUrl":"/9b770c918aeaaeb4a5c9e411f0fd15bc_s.jpg","isFollowing":false,"type":"people","slug":"viot1026","bio":"java","hash":"4beae77e4bc21","uid":596500,"isOrg":false,"description":"","profileUrl":"/people/viot1026","avatar":{"id":"9b770c918aeaaeb4a5c9e411f0fd15bc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"isFollowed":false,"name":"林泽鑫","headline":"","avatarUrl":"/da8e974dc_s.jpg","isFollowing":false,"type":"people","slug":"lin-ze-xin-94-38","bio":"react","hash":"fb38d75e01a40e67fd017c","uid":121600,"isOrg":false,"description":"","profileUrl":"/people/lin-ze-xin-94-38","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"isFollowed":false,"name":"温叶","headline":"以前的知乎给了我很多帮助,谢谢您!现在的知乎就是娱乐圈,我不玩了","avatarUrl":"/b25f876c164e6acac9ea_s.jpg","isFollowing":false,"type":"people","slug":"liu-bo-wen-19-16","bio":"知乎娱乐圈","hash":"daeb59d20caa0c","uid":64,"isOrg":false,"description":"以前的知乎给了我很多帮助,谢谢您!现在的知乎就是娱乐圈,我不玩了","profileUrl":"/people/liu-bo-wen-19-16","avatar":{"id":"b25f876c164e6acac9ea","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-ffadc267a79b0e35ec98c_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"Node.js"},{"url":"/topic/","id":"","name":"koa"},{"url":"/topic/","id":"","name":"全栈开发"}],"adminClosedComment":false,"titleImageSize":{"width":1920,"height":1080},"href":"/api/posts/","excerptTitle":"","tipjarState":"activated","tipjarTagLine":"真诚赞赏,手留余香","sourceUrl":"","pageCommentsCount":22,"tipjarorCount":3,"annotationAction":[],"hasPublishingDraft":false,"snapshotUrl":"","publishedTime":"T22:52:32+08:00","url":"/p/","lastestLikers":[{"bio":"程序员","isFollowing":false,"hash":"8ebd18a53fa3","uid":551400,"isOrg":false,"slug":"zhou-yun-hui-17","isFollowed":false,"description":"","name":"云灰暮雨","profileUrl":"/people/zhou-yun-hui-17","avatar":{"id":"v2-83fc9e10ba5b9eb6a0d3","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"没有完全放弃治疗的大学生","isFollowing":false,"hash":"efbaf0606bdcf","uid":68,"isOrg":false,"slug":"jie-dong-xi-de-xiao-ai-ren","isFollowed":false,"description":"这个人拒绝接受一辈子平庸这个可能性,因此常常显得焦躁","name":"借东西的小矮人","profileUrl":"/people/jie-dong-xi-de-xiao-ai-ren","avatar":{"id":"7636992ecaabdd1569818ddf0da81388","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"9ff2bf93da2f271f135b60f837d9279b","uid":92,"isOrg":false,"slug":"k-r-o-s","isFollowed":false,"description":"","name":"蔬菜","profileUrl":"/people/k-r-o-s","avatar":{"id":"cfc138583","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"3c0cfac9c756","uid":40,"isOrg":false,"slug":"progame","isFollowed":false,"description":"","name":"progame","profileUrl":"/people/progame","avatar":{"id":"56a37d623feab9f99b9cbadb10715a3e","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"web前端","isFollowing":false,"hash":"1acdba6f7fa","uid":123300,"isOrg":false,"slug":"yu-jie-91-84-55","isFollowed":false,"description":"","name":"琉璃色","profileUrl":"/people/yu-jie-91-84-55","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"0. 前言如今nodejs变得越来越火热,采用nodejs实现前后端分离架构已被多数大公司所采用。在过去,使用nodejs大家首先想到的是大神写的,而发展到如今,更轻量,性能更好的已然成为主流,它同样出自大神手笔,如今版本已更新到了koa2,不仅…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"annotationDetail":null,"commentsCount":22,"likesCount":96,"FULLINFO":true}},"User":{"su-mu-hua-62":{"isFollowed":false,"name":"sessionboy","headline":"全栈工程师
\ngithub: /sessionboy
\n个人站点:/
sessionboy
\n知乎专栏: /sessionboy","avatarUrl":"/v2-20d0f03987db6dfebb6e3e68c268612f_s.jpg","isFollowing":false,"type":"people","slug":"su-mu-hua-62","bio":"全栈工程师","hash":"a68812cae4a25e23afd99e8c2fc25307","uid":915600,"isOrg":false,"description":"全栈工程师
\ngithub: /sessionboy
\n个人站点:/
sessionboy
\n知乎专栏: /sessionboy","profileUrl":"/people/su-mu-hua-62","avatar":{"id":"v2-20d0f03987db6dfebb6e3e68c268612f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{"experimentFeatures":{"ge3":"ge3_9","ge2":"ge2_1","nwebStickySidebar":"sticky","newMore":"new","liveReviewBuyBar":"live_review_buy_bar_2","liveStore":"ls_a2_b2_c1_f2","isOffice":"false","homeUi2":"default","answerRelatedReadings":"qa_recommend_with_ads_and_article","remixOneKeyPlayButton":"headerButton","qrcodeLogin":"qrcode","newBuyBar":"livenewbuy3","newMobileColumnAppheader":"new_header","zcmLighting":"zcm","favAct":"default","appStoreRateDialog":"close","mobileQaPageProxyHeifetz":"m_qa_page_nweb","iOSNewestVersion":"4.2.0","default":"None","wechatShareModal":"wechat_share_modal_show","qaStickySidebar":"sticky_sidebar","androidProfilePanel":"panel_b"}},"columns":{"next":{}},"columnPosts":{},"columnSettings":{"colomnAuthor":[],"uploadAvatarDetails":"","contributeRequests":[],"contributeRequestsTotalCount":0,"inviteAuthor":""},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"drafts":{"draftsList":[],"next":{}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"edition":{},"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{},"message":{"newCount":0},"pushNotification":{"newCount":0}}

我要回帖

更多关于 koa2 怎么处理错误 的文章

 

随机推荐