5

koa2 在koa1 基础上提供了一种更好的异步流程控制方案--await-async,await-async可以让异步逻辑用同步写法实现,如下面的例子:

function getSyncTime() {
  return new Promise((resolve, reject) => {
    try {
      let startTime = new Date().getTime()
      setTimeout(() => {
        let endTime = new Date().getTime()
        let data = endTime - startTime
        resolve( data )
      }, 500)
    } catch ( err ) {
      reject( err )
    }
  })
}

async function getSyncData() {
  let time = await getSyncTime()
  let data = `endTime - startTime = ${time}`
  return data
}

async function getData() {
  let data = await getSyncData()
  console.log( data )
}

getData()

该方案的关键词是 await 和 async,需要注意的是 最底层的 await 调用函数必须返回一个Promise对象,例如get SyncTime() 必须返回一个Promise对象。

下面介绍 koa2 与 mongoose 的结合,实现查询功能。

var mongodb = require('../config.js');
var Schema = mongodb.mongoose.Schema;

/**
 *  schema
 **/
var departmentSchema = new Schema({
    id: String, //部门编号
    name: String //名称
});


/**
 *  schemao
 **/
var employeeSchema = new Schema({
    id: Number, //工号
    name: String, //姓名
    sex: Number, //性别
    age: Number, //年龄
    // dep_id: String //部门
    dep: {
        type: Schema.Types.ObjectId,
        ref: 'department'
    }
});


// Instances of Models are documents. 
// Documents have many of their own built-in instance methods. 
// We may also define our own custom document instance methods too.
// NOTE: methods must be added to the schema before compiling it with mongoose.model()
employeeSchema.methods.printInfo = function() {
    var greeting = this.name;
    console.log("Testing methods defined in schema:" + greeting);
}

/**
 *  model
 **/
var employee = mongodb.mongoose.model("employee", employeeSchema);
var department = mongodb.mongoose.model('department', departmentSchema);

var employeeDAO = function() {};

//We can access all of the employee documents through our employee model.
employeeDAO.prototype.findAll = async function(callback) {
    let list = await employee.find({}).populate({ path: 'dep', select: { name: 1 } }).exec(); 
    return list
}

module.exports = new employeeDAO();

在上述代码中,定义了schema、model,并提供了一个数据库查询 DAO 对象。由于 mongoose 的保存、查询等异步操作返回的是Promise对象结果,所以直接可以通过 await 方法调用 mongooseAPI,如

await employee.find({}).populate({ path: 'dep', select: { name: 1 } }).exec();

mongoose API 可参考这里

下面通过调用DAO实现查询功能:

const Router = require('koa-router')

let employee = require('./../models/employee.js');
let employeeList = new Router()


employeeList.get('/', async(ctx) => {
    var result = await employee.findAll();
    await ctx.render('list', {
        employeeList: result
    })
})

module.exports = employeeList;

需要注意的是,由于 DAO 中的 findAll 函数内部通过 await 调用了一个异步查询,所以 findAll 函数需要用 async 关键词声明。

本demo源码可参考这里

Express 结合 mongoose 的使用请参考我之前的文章


追寻
317 声望20 粉丝

混迹杭州 朝全栈的方向努力着...