node.js是JavaScript运行在服务端的框架,采用单线程,异步事件回调方式,由于其在web服务上优异的性能,越来越多的成为开发web服务和中间件的选择,其最大社区npm发展也异常迅猛。但是因为异步回调导致的回调地狱,困扰着广大的程序员,其发展也受到阻碍。
为了解决这个问题,出现了各种各样的解决方案。ES5时代,只能使用第三方库:例如async库,promise。async谈不上优雅,只能说解决了问题而已,代码晦涩难懂,程序流也有点混乱。promise虽然没有了回调地狱,却带来了满天飞的then。此时express是node.js的第一个web框架。
ES官方提供了自己的解决方案,迅速制定了新的标准ES6。ES6中带来了Generator函数,配合yield语句,实现程序的暂停执行和恢复执行,将底层异步函数变为同步执行。于是,基于ES6的二代web框架koa出现了。Generator函数并不是包治百病,脱离koa框架需要而外封装,比如co库。总之,ES官方组织他们对于Generator函数是不满意的,于是ES7以迅雷不及掩耳之势冲出江湖。
ES8中采用async/await这个目前为止,异步回调最佳的解决方案。质上讲,async/await规范是Generator函数+yield语句的语法糖。返回部分都是一个Promise对象。async/await比Generator函数+yield语句要更加优雅好用。node.js少不了又基于ES7搞出了第三代web框架koa2。
node.js这样迅速的发展,也许你还在用express框架,koa2框架都出来了(目前koa官网默认是koa2,koa已经成为历史)。express的异步处理实在是太....,升级koa2吧,这又是个大工程。还好async/await可以让你保持原有框架,并优雅的解决回调地狱的问题。看下面的例子:
原有express+Promise接受请求并返回数据的例子:
router.post('/find', function (req, res, next) {
let params = req.body;
let con = {
gameId: params.gameId
};
messageDao.findOne(con).then((data) => {
if (!data) {
return res.json({ code: -1, msg: '消息不存在' });
}
res.json({code: 0,message: "success",data: data});
});
});
使用async/await:
router.post('/find', async function (req, res, next) {
let params = req.body;
let con = {
gameId: params.gameId
};
let data = await messageDao.findOne(con);
if (!data) {
return res.json({ code: -1, msg: '消息不存在' });
}
res.json({code: 0,message: "success",data: data});
});
使用 async/await后,基本同写同步的Java代码没啥区别,加上ES6中就已经提供的class,可以实现面向对象的封装、继承特性。还有指令式语言的for循环控制流。总之,node.js正在将函数式语言和指令式语言的优点都采纳过来,甚至coffeeScript的语法糖也引入到新的ES标准中。大有海纳百川趋势,相信node.js未来发展会更好。