async庫是npm上的一個處理異步操做的超級庫,能夠實現不少異步操做和流程控制。雖然一些簡單的異步控制咱們可使用Promise或者async/await語法來實現,可是遇到異步流程較多的狀況咱們將難以處理。node
本文主要介紹async在node環境中配合mongoose實現數據庫分頁和async配合mongoose查詢查詢連續n天的天天數據。git
npm i async
官方文檔github
並行運行功能的任務集合,而無需等待上一個功能完成。 若是任何一個函數將錯誤傳遞給其回調,則當即使用錯誤的值調用主回調。 任務完成後,結果將做爲數組或者對象傳遞到最終回調。shell
async.parallel({ one: function(callback) { setTimeout(function() { callback(null, 1); }, 200); }, two: function(callback) { setTimeout(function() { callback(null, 2); }, 100); } }, function(err, results) { // results is now equals to: {one: 1, two: 2} });
依次運行任務集合中的功能,每個都在上一個功能完成後運行。 若是系列中的任何函數將錯誤傳遞給其回調,則不會再運行任何函數,而且會當即使用錯誤的值調用回調。 不然,當任務完成時,回調將收到結果數組。
也可使用對象而不是數組。 每一個屬性都將做爲函數運行,而且結果將做爲對象而不是數組傳遞到最終回調。 這是處理async.series結果的一種更易讀的方法。數據庫
async.series({ one: function(callback) { setTimeout(function() { callback(null, 1); }, 200); }, two: function(callback){ setTimeout(function() { callback(null, 2); }, 100); } }, function(err, results) { // results is now equal to: {one: 1, two: 2} });
知道上面的兩個關鍵api咱們就能夠來完成一些函數的應用了。npm
const mongoose = require('mongoose') const async = require('async') /**分頁 * page, pageSize, Model, populate = '', queryParams = {}, sortParams * @param {*} options */ exports.queryPagination = (options = {}, callback) => { let { page, pageSize, Model, populate = '', queryParams = {}, sortParams, field = '' } = options let start = (page - 1) * pageSize let $page = { pageNumber: page } async.parallel( { count: function(cb) { Model.countDocuments(queryParams).exec(cb) }, data: function(cb) { Model.find(queryParams) .skip(start) .limit(pageSize) .populate(populate) .sort(sortParams) .select(field) .exec(cb) } }, function(err, results) { let count = results.count $page.count = count $page.pageTotal = Math.ceil(count / pageSize) $page.data = results.data callback(err, $page) } ) }
以查詢最近7天都訪問趨勢爲例編程
/** * 7天訪問趨勢 */ exports.dayViewsController = (req, res) => { // 獲取最近7天的日期 const days = get7day() // async.series的對象參數 const parallelQuerys = {} days.forEach((day) => { let startDate = new Date(day).getTime() let lastDate = new Date( moment(startDate).add(1, 'days').format('YYYY-MM-DD') ).getTime() parallelQuerys[String(day)] = function (cb) { Vistor.countDocuments({ browse_time_stamp: { $gte: startDate, $lt: lastDate, }, }).exec(cb) } }) async.series(parallelQuerys, function (err, results) { if (err) { responseError({ err, res }) } else { responseSuccess({ res, data: results }) } }) }
對於異步編程模型來講,在同步編程中很容易作到的事情,如今卻變得很麻煩,async的流程控制大大簡化了不少複雜的操做,使用async庫來編寫數據庫的查詢流程也變得及其簡單。api