KOA 

基于Nodejs的下一代Web框架

简介

Express 团队开发,更小,更健壮,更优雅

特点

  • 解决繁琐异步回调嵌套
  • 中间件编程
  • 轻量

异步变同步

//1.0
app.use(function *(){
  yield newUser.save();
  this.body = {
    word: 'save succeed!'
  };
});

//2.0
app.use(async  function (ctx, next){
  await newUser.save()
  ctx.body = {
    word: 'save succeed!'
  }
});

Generator

  • *
  • yield
  • next()

Nodejs: node 0.11.x +     --harmony

浏览器:[链接]

Async(ES7)

  • async
  • await

Generator函数的语法糖

与Generator 好处

  • 内置执行器
  • 更好的语义
  • 更广的适用性
  • 返回值是Promise

浏览器:[链接]

Nodejs: 7.0 +  --harmony

中间件编程

代码级联

中间件编程

//2.0
var koa = require('koa');
var app = koa();

// x-response-time

app.use(async (ctx, next){
  var start = new Date;
  await next();
  var ms = new Date - start;
  this.set('X-Response-Time', ms + 'ms');
});

// logger

app.use(async (ctx, next){
  var start = new Date;
  await next();
  var ms = new Date - start;
  console.log('%s %s - %s', this.method, this.url, ms);
});

// response

app.use(asyc (ctx, next){
  ctx.body = 'Hello World';
});

app.listen(3000);

脚手架

|-common/ 一些公用方法
|-config/ 配置文件
|-models/ 数据Model层
|-routes/ 路由文件
|-index.js 应用的主要入口
|-routes.js 路由声明文件
|-package.json 声明各种依赖

Main

var router = require('koa-router')()
var koa = require('koa')
var mongoose = require('mongoose')
var statics = require('koa-static-folder')
var fs=require('fs')
var app = module.exports = new koa()

//config
var config = require('./config/config')

//connect to database
var mongoUrl = config.mongo.host + ':' + config.mongo.port + '/' + config.mongo.database
mongoose.connect(mongoUrl)
var db = mongoose.connection.on("error", function (err) {
    console.log(err)
})

//load models
var modelsPath = "./models"
fs.readdirSync(modelsPath).forEach(function (file) {
    if (~file.indexOf("js")) {
        require(modelsPath + "/" + file)
    }
})

// routes
require("./routes")(app, router)

if (!module.parent) app.listen(config.port, function () {
    console.log('listening to http://localhost:' + config.port)
})

Routes

var index = require('./routes/index'),
    add = require('./routes/add'),
    show = require('./routes/show')

module.exports = function(app, router) {
  app.use(router.routes())
  app.use(router.allowedMethods())
  router.get('/', index)
  router.post('/add', add)
  router.get('/show', show)
}

Models

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var userSchema = new Schema({
  name : String,
  password : String,
  mail : String,
  createTime : { type: Date, default: Date.now }
})

mongoose.model('user', userSchema)

Function

var mongoose = require('mongoose'),
  user = mongoose.model('user')

module.exports = async function (ctx, next) {
  var users = await user.find({
    name: 'xiaoming'
  }).exec(function(doc, error) {
    if (error) {
      console.log(error)
    }
  })
  ctx.body = users
}

APIS

  • app.listen(...)
  • app.callback()
  • app.use(function)
  • app.keys

错误处理

app.on('error', function(err, ctx){
  log.error('server error', err, ctx);
});

Context(上下文)

  • ctx.req
  • ctx.res
  • ctx.request
  • ctx.response
  • ctx.app
  • ctx.cookies.get()
  • ctx.cookies.set()
  • ctx.throw(msg, [status])

Request aliases

  • ctx.header
  • ctx.method
  • ctx.method=
  • ctx.url
  • ctx.url=
  • ctx.originalUrl
  • ctx.path
  • ctx.path=
  • ctx.query
  • ctx.query=
  • ctx.querystring
  • ctx.querystring=
  • ctx.host
  • ctx.hostname
  • ctx.fresh
  • ctx.stale
  • ctx.socket
  • ctx.protocol
  • ctx.secure
  • ctx.ip
  • ctx.ips
  • ctx.subdomains
  • ctx.is()
  • ctx.accepts()
  • ctx.acceptsEncodings()
  • ctx.acceptsCharsets()
  • ctx.acceptsLanguages()
  • ctx.get()

Response aliases

  • ctx.body
  • ctx.body=
  • ctx.status
  • ctx.status=
  • ctx.length=
  • ctx.length
  • ctx.type=
  • ctx.type
  • ctx.headerSent
  • ctx.redirect()
  • ctx.attachment()
  • ctx.set()
  • ctx.remove()
  • ctx.lastModified=
  • ctx.etag=

Koa.io

koa + socket.io

🌰

var koa = require('koa.io'),
    common = require('./common/common'),
    app = koa();

// middleware for koa
app.use(function*() {});
// middleware for socket.io's connect and disconnect
app.io.use(function*(next) {
    // on connect
    app.io.route('join', function*() {
        var id = this.data[0];
        console.log((id ? id : '默认画板') + '进人了!');
        this.join(id);
        app.io.route('draw Curve', function*() {
            this.broadcast.to(this.rooms[1]).emit('draw Curve', this.data[0]);
        });
        app.io.route('draw Point', function*() {
            this.broadcast.to(this.rooms[1]).emit('draw Point', this.data[0]);
        });
        app.io.route('clear Pad', function*() {
            this.broadcast.to(this.rooms[1]).emit('clear Pad', this.data[0]);
        });
    });
    yield* next;
    // on disconnect
});

app.listen(9201);

谢谢!

KOA

By weiwei ggice

KOA

Talk PPT

  • 15