koa學習之路三

以前的文章咱們介紹了一下 koa 路由,get 傳值,動態路由,本節咱們看一下 koa 中間件 以及 koa 中間件的洋蔥圖執行流程。html

1、什麼是 Koa 的中間件前端

通俗的講:中間件就是匹配路由以前或者匹配路由完成作的一系列的操做,咱們就能夠把它叫作中間件。node

在express中間件(Middleware)是一個函數,它能夠訪問請求對象(request object (req)), 響應對象(response object (res)), 和 web 應用中處理請求-響應循環流程中的中間件,通常被命名爲 next 的變量。在 Koa 中中間件和 express 有點相似。web

中間件的功能包括:數據庫

  執行任何代碼。express

  修改請求和響應對象。後端

  終結請求-響應循環。app

  調用堆棧中的下一個中間件。koa

若是個人 get、post 回調函數中,沒有 next 參數,那麼就匹配上第一個路由,就不會往下匹 配了。若是想往下匹配的話,那麼須要寫 next()async

2、Koa 應用可以使用以下幾種中間件:

  應用級中間件

  路由級中間件

  錯誤處理中間件

  第三方中間件

 

咱們先來看一下應用級中間件,咱們仍是按照以前的項目將 app.js 改成以下:

//引入 koa模塊
var Koa = require('koa');
var Router = require('koa-router');

//實例化
var app = new Koa();
var router = new Router();

//匹配任何路由,若是不寫next,這個路由被匹配到了就不會繼續向下匹配
app.use(async (ctx, next) => {
    console.log("我是一箇中間件");
    // 當前路由匹配完成之後繼續向下匹配
    await next();
});

//配置路由
router.get('/', async (ctx) => {
    ctx.body = "首頁";
});
router.get('/news', async (ctx) => {
    ctx.body = "新聞列頁面";
});

//啓動路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

咱們在匹配路由以前寫了一個 app.use(async ()=>{}) 的中間件,該中間件若是不像 router.get 那樣寫一個參數 "/" 或 "/news",那麼它將匹配任何一個路由,且最早匹配,若是咱們在其中寫 next() 的話,則會終止在此,再也不向下陪陪路由,運行結果以下:

咱們在編輯器的控制檯看一下輸出日誌:

 

接下來咱們看一下路由中間件:

//引入 koa模塊
var Koa = require('koa');
var Router = require('koa-router');

//實例化
var app = new Koa();
var router = new Router();

//配置路由
router.get('/', async (ctx, next) => {
    console.log("控制檯打印");
    // 當前路由匹配完成之後繼續向下匹配
    await next();
});
router.get('/', async (ctx) => {
    ctx.body = "首頁";
});
router.get('/news', async (ctx) => {
    ctx.body = "新聞列頁面";
});

//啓動路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

在上面的代碼中咱們定義了兩個 router.get('/',  ) 的路由,第一個咱們在控制檯輸出一句話,第二個咱們想頁面輸出內容。若是在第一個裏面咱們不寫 next() 方法的話,則不會進入第二個裏面,結果以下:

控制檯打印結果

 

接下來咱們看一下錯誤處理中間件:

//引入 koa模塊
var Koa = require('koa');
var Router = require('koa-router');

//實例化
var app = new Koa();
var router = new Router();

//匹配任何路由,若是不寫next,這個路由被匹配到了就不會繼續向下匹配
app.use(async (ctx,next)=>{
    await next();
    //若是頁面找不到
    if(ctx.status==404){
        ctx.status = 404;
        ctx.body="404 頁面"
    }
});

//配置路由
router.get('/', async (ctx) => {
    ctx.body = "首頁";
});
router.get('/news', async (ctx) => {
    ctx.body = "新聞列頁面";
});

//啓動路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

咱們還按以前的應用中間件那樣寫,而後在裏面作了一個 if 語句判斷,當頁面響應時,會給後端返回一個 status 碼,這個就不在單獨說了,若是這個 status 報 404,咱們知道表示該頁面不存在,那麼咱們就能夠攔截 next() 方法,輸出給前端一個 404 頁面,結果以下:

咱們匹配了一個 "/news" 路由,能夠正常顯示內容,若是咱們不當心少寫一個 "s",寫成了 "new",結果以下:

在上面的代碼中咱們是將 if 判斷語句放在了 next() 方法以後,那能不能放在 next() 以前呢?這個問題咱們在下面的 koa 中間件流程控制中再詳細說明。

 

第三方中間件在以後的文章中咱們用到了第三方模塊時再說。

接下來我麼看一下 koa 中的中間件流程控制。

koa被認爲是第二代node web framework,它最大的特色就是獨特的中間件流程控制,是一個典型的洋蔥模型。

 

上面的兩張圖能夠很直觀的說明 koa 中的中間件流程控制。咱們接下來用代碼演示一下:

//引入 koa模塊
var Koa = require('koa');
var Router = require('koa-router');

//實例化
var app = new Koa();
var router = new Router();

app.use(async (ctx, next) => {
    console.log('一、這是第一個中間件01');
    await next();
    console.log('五、匹配路由完成之後又會返回來執行中間件');
});

app.use(async (ctx, next) => {
    console.log('二、這是第二個中間件02');
    await next();
    console.log('四、匹配路由完成之後又會返回來執行中間件');
});

router.get('/', async (ctx) => {
    console.log('三、匹配到了news這個路由');
    ctx.body = "首頁";
});

//啓動路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

咱們在上面的代碼引用了兩個應用級的中間件,分別在 next() 先後輸出日誌,當咱們訪問 localhost:3000/ 時,咱們看一下控制檯的輸出結果:

從輸出打印結果順序咱們能夠看出中間件會先逐級處理 request  請求,而後再返回來逐級處理 response 請求,這就是咱們爲何要將 錯誤處理中間件 中的 if 判斷語句放在 next() 方法以後,這樣就是在路由進入 "/news" 後返回 status = 404 的結果後再進行處理,若是放在了 next() 方法以前,則會直接判斷 if 語句,不會再向下匹配 "/news" 路由了。好比咱們的用戶登陸系統就能夠這麼用,當用戶輸入帳號密碼後出入後臺,後臺在數據庫匹配以後再進行處理,處理以後返回給前端,就是這麼玩的。

 

內容來自:http://www.javashuo.com/article/p-qmgkhtkv-ho.html

相關文章
相關標籤/搜索