最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解 Koa 框架中間件原理

 更新時(shí)間:2018年10月18日 08:40:00   作者:WEBOOK  
koa是目前node里最流行的web框架。這篇文章主要介紹了理解 Koa 框架中間件原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

Node 主要用在開發(fā) Web 應(yīng)用,koa 是目前 node 里最流行的 web 框架。

在 Node 開啟一個(gè) http 服務(wù)簡(jiǎn)直易如反掌,官網(wǎng) demo。

const http = require("http");

const server = http.createServer((req, res) => {
 res.statusCode = 200;
 res.setHeader("Content-Type", "text/plain");
 res.end("Hello World\n");
});

const hostname = "127.0.0.1";
const port = 3000;
server.listen(port, hostname, () => {
 console.log(`Server running at http://${hostname}:${port}/`);
});

  • 引入 http 模塊, http 的 createServer 方法創(chuàng)建了一個(gè) http.Server 的實(shí)例。
  • server 監(jiān)聽 3000 端口。
  • 我們傳入到 createServer 里的函數(shù)實(shí)際是監(jiān)聽 request 事件的回調(diào),每當(dāng)請(qǐng)求進(jìn)來(lái),監(jiān)聽函數(shù)就會(huì)執(zhí)行。
  • request 事件的監(jiān)聽函數(shù),其函數(shù)接受兩個(gè)參數(shù),分別是 req 和 res 。其中 req 是一個(gè)可讀流, res 是一個(gè)可寫流。我們通過(guò) req 獲取 http 請(qǐng)求的所有信息,同時(shí)將數(shù)據(jù)寫入到 res 來(lái)對(duì)該請(qǐng)求作出響應(yīng)。

koa 應(yīng)用

koa 如何創(chuàng)建一個(gè) server, 直接上個(gè)官網(wǎng)的例子

const Koa = require("koa");
const app = new Koa();

// x-response-time

app.use(async (ctx, next) => {
 const start = Date.now();
 await next();
 const ms = Date.now() - start;
 ctx.set("X-Response-Time", `${ms}ms`);
});

// logger

app.use(async (ctx, next) => {
 const start = Date.now();
 await next();
 const ms = Date.now() - start;
 console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});

// response

app.use(async ctx => {
 ctx.body = "Hello World";
});

app.listen(3000);

中間件概念在編程中使用廣泛, 不管是前端還是后端, 在實(shí)際編程中或者框架設(shè)計(jì)都有使用到這種實(shí)用的模型。

基本上,Koa 所有的功能都是通過(guò)中間件實(shí)現(xiàn)的。

每個(gè)中間件默認(rèn)接受兩個(gè)參數(shù),第一個(gè)參數(shù)是 Context 對(duì)象,第二個(gè)參數(shù)是 next 函數(shù)。只要調(diào)用 next 函數(shù),就可以把執(zhí)行權(quán)轉(zhuǎn)交給下一個(gè)中間件。

如果中間件內(nèi)部沒有調(diào)用 next 函數(shù),那么執(zhí)行權(quán)就不會(huì)傳遞下去。

多個(gè)中間件會(huì)形成一個(gè)棧結(jié)構(gòu)(middle stack),以“先進(jìn)后出”(first-in-last-out)的順序執(zhí)行。整個(gè)過(guò)程就像,先是入棧,然后出棧的操作。

上面代碼的執(zhí)行順序是:

請(qǐng)求 ==> x-response-time 中間件 ==> logger 中間件 ==> response中間件 ==> logger 中間件 ==> response-time 中間件 ==> 響應(yīng)

理解 Koa 的中間件機(jī)制(源碼分析)

閱讀源碼,化繁為簡(jiǎn),我們看看 koa 的中間件系統(tǒng)是如何實(shí)現(xiàn)的。

class Application extends Emitter {
 constructor() {
  super();
  this.middleware = [];
 },

 use(fn) {
  this.middleware.push(fn);
  return this;
 },

 callback() {
  const fn = compose(this.middleware);

  return function(req, res) {
   return fn(ctx);
  };
 },

 listen(...args) {
  const server = http.createServer(this.callback());
  return server.listen(...args);
 }
}

好了,精簡(jiǎn)結(jié)束,一不小心,去枝末節(jié),最后只剩下不到 20 行代碼。

這就是框架的核心,簡(jiǎn)化后的代碼非常清晰,有點(diǎn)不可思議,但核心就是這么簡(jiǎn)單。

我們先分析以上代碼做了什么事。

  • 我們定義了一個(gè) middleware 數(shù)組來(lái)存儲(chǔ)中間件。
  • 我們定一個(gè)了一個(gè) use 方法來(lái)注冊(cè)一個(gè)中間件。其實(shí)就是簡(jiǎn)單的 push 到自身的 mideware 這個(gè)數(shù)組中。
  • 我們還使用了一個(gè) compose 方法,傳入 middleware ,應(yīng)該是做了一些處理,返回了一個(gè)可執(zhí)行的方法。

你一定對(duì)中間的 compose 方法很好奇,初此之外的代碼都容易理解,唯獨(dú)這個(gè) compose 不太知道究竟做了什么。

其實(shí), compose 就是整個(gè)中間件框架的核心。

compose 之外,代碼已經(jīng)很清楚的定義了

  • 中間件的存儲(chǔ)
  • 中間件的注冊(cè)

而 compose 方法做了最為重要的一件事

  • 中間件的執(zhí)行

核心源碼 compose

先上碼

function compose(middleware) {
 return function(context, next) {
  // last called middleware #
  let index = -1;
  return dispatch(0);
  function dispatch(i) {
   if (i <= index)
    return Promise.reject(new Error("next() called multiple times"));
   index = i;
   let fn = middleware[i];
   if (i === middleware.length) fn = next;
   if (!fn) return Promise.resolve();
   try {
    return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
   } catch (err) {
    return Promise.reject(err);
   }
  }
 };
}

我試圖去簡(jiǎn)化一下這個(gè)方法,但方法本身已經(jīng)足夠簡(jiǎn)潔。

代碼很簡(jiǎn)潔。

通過(guò) next()傳遞 實(shí)現(xiàn)中間件調(diào)用, 結(jié)合 Promise 采用 遞歸調(diào)用 的通知機(jī)制。

看圖

這種形式的控制流讓整個(gè) Koa 框架中間件的訪問(wèn)呈現(xiàn)出 自上而下的中間件流 + 自下而上的 response 數(shù)據(jù)流 的形式。

Koa 本身做的工作僅僅是定制了中間件的編寫規(guī)范,而不內(nèi)置任何中間件。一個(gè) web request 會(huì)通過(guò) Koa 的中間件棧,來(lái)動(dòng)態(tài)完成 response 的處理。

koa 在中間件語(yǔ)法上面采用了 async + await 語(yǔ)法來(lái)生成 Promise 形式的程序控制流。

總結(jié)

koa 是非常精簡(jiǎn)的框架, 其中的精粹思想就是洋蔥模型(中間件模型), koa 框架的中間件模型非常好用并且簡(jiǎn)潔, 但是也有自身的缺陷, 一旦中間件數(shù)組過(guò)于龐大, 性能會(huì)有所下降,我們需要結(jié)合自身的情況與業(yè)務(wù)場(chǎng)景作出最合適的選擇.

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用Nodejs獲取bing每日?qǐng)D片

    使用Nodejs獲取bing每日?qǐng)D片

    這篇文章主要為大家詳細(xì)介紹了如何使用Nodejs獲取bing每日?qǐng)D片,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • Node.js系列之發(fā)起get/post請(qǐng)求(2)

    Node.js系列之發(fā)起get/post請(qǐng)求(2)

    這篇文章主要為大家詳細(xì)介紹了Node.js系列之發(fā)起get/post請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 基于nodejs+express4.X實(shí)現(xiàn)文件下載的實(shí)例代碼

    基于nodejs+express4.X實(shí)現(xiàn)文件下載的實(shí)例代碼

    本篇文章主要介紹了詳解nodejs+express4.X的文件下載的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Node.js文件操作詳解

    Node.js文件操作詳解

    這篇文章主要介紹了Node.js文件操作詳解,本文講解了處理文件路徑講的一些方法、fs模塊詳細(xì)的使用和介紹等內(nèi)容,需要的朋友可以參考下
    2014-08-08
  • Node.js包管理器代理工具Verdaccio輕松創(chuàng)建管理本地npm包倉(cāng)庫(kù)

    Node.js包管理器代理工具Verdaccio輕松創(chuàng)建管理本地npm包倉(cāng)庫(kù)

    這篇文章主要為大家介紹了Node.js包管理器代理工具Verdaccio輕松創(chuàng)建管理本地npm包倉(cāng)庫(kù)的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • nodejs dgram模塊廣播+組播的實(shí)現(xiàn)示例

    nodejs dgram模塊廣播+組播的實(shí)現(xiàn)示例

    這篇文章主要介紹了nodejs dgram模塊廣播+組播的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • nestjs中異常過(guò)濾器Exceptionfilter的具體使用

    nestjs中異常過(guò)濾器Exceptionfilter的具體使用

    這篇文章主要介紹了nestjs中異常過(guò)濾器Exceptionfilter的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 在CentOS 7服務(wù)器上安裝Node.js的方法步驟

    在CentOS 7服務(wù)器上安裝Node.js的方法步驟

    Node.js 是一個(gè)用于服務(wù)器端編程的 JavaScript 平臺(tái),允許用戶快速構(gòu)建網(wǎng)絡(luò)應(yīng)用程序,通過(guò)在前端和后端都使用 JavaScript,開發(fā)可以更加一致并且可以在同一個(gè)系統(tǒng)中設(shè)計(jì),在本指南中,我們將向您展示如何在 Ubuntu 14.04 服務(wù)器上開始使用 Node.js
    2024-09-09
  • 如何開發(fā)一個(gè)漸進(jìn)式Web應(yīng)用程序PWA

    如何開發(fā)一個(gè)漸進(jìn)式Web應(yīng)用程序PWA

    這篇文章主要介紹了如何開發(fā)一個(gè)漸進(jìn)式Web應(yīng)用程序PWA,對(duì)漸進(jìn)式Web應(yīng)用程序感興趣的同學(xué),可以參考下
    2021-05-05
  • NodeJs操作MongoDB教程之分頁(yè)功能以及常見問(wèn)題

    NodeJs操作MongoDB教程之分頁(yè)功能以及常見問(wèn)題

    這篇文章主要給大家介紹了關(guān)于NodeJs操作MongoDB教程之分頁(yè)功能以及常見問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用NodeJs具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論

买车| 陇川县| 平陆县| 岑溪市| 壤塘县| 阿瓦提县| 漳州市| 垫江县| 喜德县| 色达县| 怀化市| 如皋市| 德惠市| 兰州市| 满洲里市| 张北县| 乐至县| 五华县| 壶关县| 米脂县| 怀安县| 西昌市| 大英县| 平阳县| 通道| 手游| 九江市| 庆阳市| 古蔺县| 吉水县| 云和县| 曲麻莱县| 临武县| 策勒县| 南召县| 尉犁县| 朝阳县| 高州市| 鄂托克旗| 荆门市| 斗六市|