前言
Node.js使用了一个事件驱动、非阻塞式 I/O 的模型,使其既轻量又高效。同时这种异步编程模式带来的难点就是一个函数如果需要使用另一个函数的的返回值,那么就会陷入层层回调的地狱中。 试想如果有这么一个机制或模块可以让N个函数异步并行执行,我们在这些函数全部执行成功后再统一做一些业务处理是不是能大幅提升系统性能,爽到爆。
Async 介绍
前面提到Node.js异步编程带来的一些问题,不过这都不是事。咱们应该庆幸程序猿是这个世界上最聪明的动物,也应该感谢那些为开源无私奉献的程序猿。博主自己也是开源的狂热者并正在努力为开源贡献力量。
Async做为Node.js的一个异步编程模块,提供了大约20多个流程控制方法,常用到的有 series, parallel, waterfall, auto这四种 ,完全可以满足我们的开发需求。我们今天主要讲解 parallel 模式 在项目的应用。
Async安装方式:npm install async
Async parallel 模式介绍
parallel 调用格式:parallel(tasks,[callback]),tasks可以是一个数组或json对象。
parallel 函数是并行执行多个函数,每个函数都是立即执行,不需要等待其他函数先执行。传递给最终callback数组中的数据是tasks的声明顺序而不是函数的执行顺序。
async.parallel([ function(callback){ callback(null, 'one'); }, function(callback){ callback(null, 'two'); }],function(err, results){ console.log(results);//打印结果为 ['one','two'] });
使用 parallel 优化我们的分页
在我们的案例博客系统中,后台有个分页展示文章列表的功能,界面效果如下:
与之对应我们后台代码实现过程为:
/* 博客文章列表页面 */ route.get("/list",function(req,res,next){ pageData.pageIndex=req.query.p || 1; article_model.count(function(err,count){ if(err){ return; } pageData.total=count; //使用 populate 进行表关联 var query=article_model.find({isDell:false}).populate('_category',{name:1}) .skip((pageData.pageIndex-1)*pageData.pageSize) .limit(pageData.pageSize); query.exec(function(err,docs){ pageData.data=docs; res.render("admin/article/list",pageData); }); }) });
从代码中可以看出我们先进行了count的查询,获取到了文章总数量,然后在回调函数中分页查询了一定数量的文章。
接下来我们使用Async 的 parallel进行改造,提升性能(请先在在js文件顶部使用 require 引入async模块)。
/* 博客文章列表页面 */ route.get("/list",function(req,res,next){ pageData.pageIndex=req.query.p || 1; async.parallel([ function(callback){ //获取文章总数量 article_model.count(function(err,count){ callback(null,count); }); }, function(callback){ //使用 populate 进行表关联 var query=article_model.find({isDell:false}).populate('_category',{name:1}) .skip((pageData.pageIndex-1)*pageData.pageSize) .limit(pageData.pageSize); query.exec(function(err,docs){ callback(null,docs); }); }],function(err, results){ pageData.total=results[0]; pageData.data=results[1]; res.render("admin/article/list",pageData); }); });
评论列表
评论内容: