1. 程式人生 > >nodeJs--koa2入門

nodeJs--koa2入門

1、koa2背景

Express簡介:

koa是Express的下一代基於Node.js的web框架,目前有1.x和2.0兩個版本. 雖然Express的API很簡單,但是它是基於ES5的語法,要實現非同步程式碼,只有一個方法:回撥。

如果非同步巢狀層次過多,程式碼寫起來就非常難看, 雖然可以用async這樣的庫來組織非同步程式碼,但是用回撥寫非同步實在是太痛苦了!

koa 1.0簡介:

隨著新版Node.js開始支援ES6,Express的團隊又基於ES6的generator重新編寫了下一代web框架koa。和Express相比,koa 1.0使用generator實現非同步。

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

app.use('/test', function *() {
    yield doReadFile1();
var data = yield doReadFile2();
this.body = data;
});

app.listen(3000);

用generator實現非同步比回撥簡單了不少,但是generator的本意並不是非同步。Promise才是為非同步設計的,但是Promise的寫法……想想就複雜。因此2.0應運而生。

koa 2.0簡介:

koa團隊並沒有止步於koa 1.0,他們非常超前地基於ES7開發了koa2,和koa 1相比,koa2完全使用Promise並配合async來實現非同步。

app.use(async (ctx, next) => {
    await next();
    //ctx --  context上下文:ctx是Koa傳入的封裝了request和response的變數
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, Koa2!</h1>'
});

什麼感覺?是不是很爽?非同步-同步的感覺

2、koa2入門

步驟一:新建資料夾 learnKoa

步驟二:新建 app.js

'use strict';
const Koa = require('koa');

const app = new Koa();
app.use(async (ctx, next) => {
    await next();
    //ctx --  context上下文:ctx是Koa傳入的封裝了request和response的變數
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, Koa2!</h1>'
})

app.listen(3000)
console.log('app started at port 3000...');

步驟三:新建 package.json

{
    "name": "learn-koa2",
    "version": "1.0.0",
    "description": "learn Koa 2",
    "main": "app.js",
    "scripts": {
        "start": "node app.js"
    },
    "keywords": [
        "koa",
        "async"
    ],
    "author": "david pan",
    "dependencies": {
        "koa": "2.0.0"
    }
}

步驟四:npm install

步驟五:npm run start, 瀏覽器開啟http://localhost:3000/,恭喜你,踏上新的征途!

3、koa middleware

async函式稱為middleware

'use strict';
const Koa = require('koa');

const app = new Koa();

app.use(async (ctx, next) => {
    console.log(`${ctx.request.method} ${ctx.request.url}`);
 // 列印URL
    await next(); 
 // 呼叫下一個middleware
});

app.use(async (ctx, next) => {    
    const start = new Date().getTime(); 
    // 當前時間
    await next();
    // 呼叫下一個middleware
    const ms = new Date().getTime() - start;
    // 耗費時間
    console.log(`Time: ${ms}ms`);
    // 列印耗費時間
});

app.use(async (ctx, next) => {
    await next();
    //ctx --  context上下文:ctx是Koa傳入的封裝了request和response的變數
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, Koa2!</h1>'
});

app.listen(3000);
console.log('app started at port 3000...');

注意點:

a. koa把很多async函式組成一個處理鏈,每個async函式都可以做一些自己的事情,然後用await next()來呼叫下一個async函式。

b. middleware的順序很重要,也就是呼叫app.use()的順序決定了middleware的順序。

c. 如果一個middleware沒有呼叫await next(), 後續的middleware將不再執行。

例如:一個檢測使用者許可權的middleware可以決定是否繼續處理請求,還是直接返回403錯誤

app.use(async (ctx, next) => {
if (await checkUserPermission(ctx)) {
        await next();
    } else {
        ctx.response.status = 403;
    }
});