koa學習(1)

koa是Express的下一代基於Node.js的web框架,目前有1.x和2.0兩個版本。

koa 1.0 用es6的generator來實現異步

doreadFile()等有值時就返回。

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

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

app.listen(3000);

爲了簡化異步代碼,es7引入了關鍵字async和await,可以輕鬆把一個function變爲一個異步模式。例如如下:

app.use(async (ctx, next) => {
    await next();
    var data = await doReadFile();
    ctx.response.type = 'text/plain';
    ctx.response.body = data;
});

創建koa項目 使用npm init創建node 項目,其中有package.json文件,是整個項目的配置文件,如下內容。

//post 請求中用來解析參數bodyparser
const bodyparser = require('koa-bodyparser');
//使用
app.use(bodyParser());
{
    "name": "hello-koa2",
    "version": "1.0.0",
    "description": "Hello Koa 2 example with async",
    "main": "app.js",
    "scripts": {
        "start": "node app.js"
    },
    "keywords": [
        "koa",
        "async"
    ],
    "author": "Michael Liao",
    "license": "Apache-2.0",
    "repository": {
        "type": "git",
        "url": "https://github.com/michaelliao/learn-javascript.git"
    },
    "dependencies": {
        "koa": "2.0.0",
        "koa-router": "7.0.0",
        "koa-bodyparser": "3.2.0"
    }
}

表示一些描述文件,scripts 表示入口文件 本文中是app.js文件。dependence表示引用的包。

導入koa 

//導入koa 導入的是一個class 因此用大寫的Koa表示
const Koa = require('koa');
//創建一個Koa對象表示web app本身
const app = new Koa();

對於每一個http請求,koa將調用我們傳入的異步函數來處理。

app.use(async(ctx,next) =>{
    console.log("process");
    await next();
});

參數ctx表示上下文,封裝了request和response變量,,我們可以通過它訪問request和response,next是koa傳入的將要處理的下一個異步函數。上面函數中 使用await next()表示處理下一個異步函數,只有等這個處理完了,才能執行下面的代碼。

app.listen表示監聽的端口。

await next()的作用。 koa把async函數組成一個處理鏈,買個async函數都可以做一些自己的函數,然後用await next()來調用下一個async函數,我們把每個async函數稱爲middleware 中間件,這些middleware可以組合起來,完成很多有用的功能。

我們可以寫如下函數來查看middleware的調用順序。

app.use(async(ctx,next)=>{
   console.log("1"); //等這裏執行好 調用下一個異步函數
 
    await next();
    console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
 
});
app.use(async(ctx,next) => {
    const start = new Date().getTime(); // 當前時間
    console.log(2);
    await next();
    const ms = new Date().getTime() - start; //等異步函數執行好 再執行這裏 耗費時間
    console.log(`Time: ${ms}ms`); // 打印耗費時間
});
app.use(async(ctx,next)=>{
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>cdda<h1>';
})

依次打印出1 2 3所以可見順序是看app.use的加載順序。在await next()執行完畢後才執行下面的語句。

koa中的路由是一個非常重要的概念,在其中根據不同的路由執行不同的邏輯順序。

使用koa-router

// 注意require('koa-router')返回的是函數:
const router = require('koa-router')();

定義路由

// add url-route:
router.get('/hello/:name', async (ctx, next) => {
    var name = ctx.params.name;
    ctx.response.body = `<h1>Hello, ${name}!</h1>`;
});

router.get('/', async (ctx, next) => {
    ctx.response.body = '<h1>Index</h1>';
});

隨後使用router

// add router middleware:
app.use(router.routes());

注意導入koa-router的語句最後的()是函數調用:

處理post請求。

post請求通常有表單,或者將參數放在body中,但無論是Node.js提供的原始request對象,還是koa提供的request對象,都不提供解析request的body的功能! 所以我們用koa-bodyparser來解析。

這裏要注意的是。koa-bodyparser必須在router之前被註冊到app對象中。

接下來,就可以處理簡單的post請求了。

var getuser = async (ctx, next) => {
    var
        name = ctx.request.body.name || '',
        password = ctx.request.body.password || '';
        console.log(name);
        ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
   
};

這樣就可以簡單的處理請求並返回。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章