亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

koa2源碼分析

ningwang / 3385人閱讀

摘要:下面基于構(gòu)造函數(shù)入口做進一步分析。創(chuàng)建一個空數(shù)組存放放,洋蔥流程的真相下面會分析法到?jīng)Q定忽略的子域名數(shù)量,默認為處理環(huán)境變量實例上掛載說明上面是構(gòu)造函數(shù)入口啟動入口如下借用原生,添加。

引言

最近在寫koa2相關(guān)例子,順便看了下koa2的源碼,下面是一些個人理解。

koa1核心基于generator,但是嚴重依賴co的包裝。koa2完全不需要,基于async(其實質(zhì)是generator的語法糖調(diào)用包裝),在node v7 下可直接運行。
關(guān)于async和generator的語法,本文不做贅述。下面先創(chuàng)建一個koa實例,然后基于入口一步步分析。

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

app.use(async function (ctx, next) {
    console.log(">> one");
    await next();
    console.log("<< one");
});
app.use(ctx => {
    ctx.body="hello world gcy";
});
app.listen("3000",function () {
    console.log("listening on port 3000");
});

說明 上面這段代碼似乎有些神秘,其實質(zhì)是下面http module的封裝調(diào)用。

// native code
let http=require("http");
let server=http.createServer(function (req,res) {
    res.writeHead(200,{"Content-type":"text/plain"});
    res.write("hello world gcy");
    res.end();
});
//start service listen
server.listen(8000,function () {
    console.log("listening on port 8000");
});

下面基于koa構(gòu)造函數(shù)入口做進一步分析。

constructor() {
    super();

    this.proxy = false;
    //創(chuàng)建一個空數(shù)組存放放middleware,洋蔥流程的真相,下面會分析法到
    this.middleware = [];
    //決定忽略的子域名數(shù)量,默認為2
    this.subdomainOffset = 2;
    //處理環(huán)境變量
    this.env = process.env.NODE_ENV || "development";
    //實例上掛載context,request,response
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }

說明 上面是構(gòu)造函數(shù)入口,啟動入口如下

 //借用原生http.createServer,添加app.callback。
  listen() {
    debug("listen");
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

說明 通過上面兩個步驟一個完整的web服務(wù)器建立起來。對于監(jiān)聽接受到的請求解析處理,是通過callback函數(shù),調(diào)用一系列中間件來完成。
下面分析中間件執(zhí)行流程,我認為koa的主要內(nèi)涵也就在這,所以做一下重點來論述。
首先引入經(jīng)典中間件洋蔥圖,以便理解。

結(jié)合這幅圖再看下面的代碼

////核心代碼application 126 行  const fn = compose(this.middleware);
 return function (context, next) {
    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
      //立即返回處于resolve狀態(tài)promise實例,以便后續(xù)邏輯繼續(xù)執(zhí)行
      if (!fn) return Promise.resolve()
      try {
     
        //   await next();  //當fn里面執(zhí)行這句話時,就會執(zhí)行dispatch(i+1),導(dǎo)致洋蔥執(zhí)行過程
        //   整個過程類似堆棧執(zhí)行釋放過程中的的遞歸調(diào)用,雖然有差異,可借用類比思考其執(zhí)行順序流程
        return Promise.resolve(fn(context, function next () {
          return dispatch(i + 1)
        }))
      } catch (err) {
        return Promise.reject(err)
      }
    }
    // 核心代碼application 136 行 return fn(ctx)[是一個立即狀態(tài)的promise].then(handleResponse).catch(onerror);
  }
}

如果結(jié)合注釋看上述代碼過程中存在疑惑,可進一步參考下面的進行思考,反之忽略即可。

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


app.use(async function (ctx, next) {
    console.log(">> one");
    await next();
    console.log("<< one");
});
app.use(async function (ctx, next) {
    console.log(">> two");
    ctx.body = "two";
    await next();
    console.log("<< two");
});
app.use(async function (ctx, next) {
    console.log(">> three");
    await next();
    console.log("<< three");
});
//如果放到首部,不方便理解洋蔥執(zhí)行流程,因為沒有調(diào)用next函數(shù)
app.use(ctx => {
    ctx.body="hello world gcy";
});
app.listen("3000",function () {
    console.log("listening on port 3000");
});

說明 koa基于中間價架構(gòu),核心簡潔,除此之外還有一些其它相對重要的方法。

application.js

use(fn) //組裝use的傳參

createContext(req, res) 創(chuàng)建初始化的上下文,將req和res掛載在context上

onerror(err) 錯誤處理,當設(shè)定this.slient為true,不會輸出信息,在emit觸發(fā)時執(zhí)行

respond(ctx) http response簡單封裝,信息返回

context.js

delegate(proto, "request") //Request相關(guān)方法委托,從而讓context作為調(diào)用入口

onerror(err) //中間件執(zhí)行過程中異常處理邏輯

除此之外還有request和response的參數(shù)解析文件,因為邏輯簡單,不做敘述。
雖然核心文件不多,但是其也require了不少包,下面列舉幾個比較重的,以作為示例。

require

events application繼承自Emitter,從而可以實現(xiàn)事件的訂閱發(fā)布。

koa-compose 中間件的封裝,核心邏輯之一,上面已分析。

debug 錯誤信息格式封裝處理

statuses http狀態(tài)碼和和相應(yīng)信息對應(yīng)處理

koa-convert 把generator轉(zhuǎn)為promise

…… and so on

總結(jié)

寫這篇文章起因,是在寫case的過程中,同一解決方案下中間件選擇的糾結(jié)癥,尤其是在選擇render template過程中,為找其本質(zhì)間差異,探尋到此。
源碼分析基于koa(version 2.2.0),通讀源碼之后,可以較清晰的開發(fā)或者使用別人的中間件,
如果你有不同的理解,歡迎留言交流。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/82202.html

相關(guān)文章

  • koa2 一網(wǎng)打盡(基本使用,洋蔥圈,中間件機制和模擬,源碼分析(工程,核心模塊,特殊處理),核心點

    摘要:洋蔥圈處理模型?;诘撵`活強大的中間件機制。參考官網(wǎng)提供的基本,不在贅述部分實現(xiàn),參考源碼分析常用服務(wù)端口監(jiān)聽返回適用于方法的回調(diào)函數(shù)來處理請求。 本文 github 地址: https://github.com/HCThink/h-blog/blob/master/source/koa2/readme.md github 首頁(star+watch,一手動態(tài)直達): https:...

    william 評論0 收藏0
  • Koa源碼閱讀筆記(4) -- ctx對象

    摘要:本筆記共四篇源碼閱讀筆記源碼閱讀筆記源碼閱讀筆記服務(wù)器啟動與請求處理源碼閱讀筆記對象起因前兩天終于把自己一直想讀的源代碼讀了一遍。首先放上關(guān)鍵的源代碼在上一篇源碼閱讀筆記服務(wù)器啟動與請求處理中,我們已經(jīng)分析了的作用。 本筆記共四篇Koa源碼閱讀筆記(1) -- coKoa源碼閱讀筆記(2) -- composeKoa源碼閱讀筆記(3) -- 服務(wù)器の啟動與請求處理Koa源碼閱讀筆記(4...

    ityouknow 評論0 收藏0
  • 通過實例分析javascript中的“中間件”

    摘要:如果驗證沒出現(xiàn)問題,就注冊這個中間件并放到中間件數(shù)組中。但如果不執(zhí)行,中間件的處理也會終止。整理下流程默認會執(zhí)行中間件數(shù)組中的第一個,也就是代碼中的,第一個中間件通過返回的是第二個中間件的執(zhí)行。 介紹 如果你使用過redux或者nodejs,那么你對中間件這個詞一定不會感到陌生,如果沒用過這些也沒關(guān)系,也可以通過這個來了解javascript中的事件流程。 一個例子 有一類人,非常的懶...

    zhangyucha0 評論0 收藏0
  • react + koa2實現(xiàn)的論壇

    摘要:頁面預(yù)覽頁面主要分為話題列表頁消息頁面?zhèn)€人信息頁面創(chuàng)建話題頁面?zhèn)€人設(shè)置頁面注冊頁面登陸頁面頁面。還有權(quán)限方面的,比如登陸后不可以再進入登陸頁面,未登陸也不可以進入創(chuàng)建主題頁面。沒有使用,但推介使用,不然性能不好。 技術(shù)棧 線上地址:點擊查看 (訪問會有點慢,至于原因,下面會說明)前端(主要):reactv15.6.1、react routerv4.2.0、reduxv3.7.2、ant...

    jk_v1 評論0 收藏0
  • KOA2框架原理解析和實現(xiàn)

    摘要:實現(xiàn)的四大模塊上文簡述了源碼的大體框架結(jié)構(gòu),接下來我們來實現(xiàn)一個的框架,筆者認為理解和實現(xiàn)一個框架需要實現(xiàn)四個大模塊,分別是封裝創(chuàng)建類構(gòu)造函數(shù)構(gòu)造對象中間件機制和剝洋蔥模型的實現(xiàn)錯誤捕獲和錯誤處理下面我們就逐一分析和實現(xiàn)。 什么是koa框架? ? ? ? ?koa是一個基于node實現(xiàn)的一個新的web框架,它是由express框架的原班人馬打造的。它的特點是優(yōu)雅、簡潔、表達力強、自由度...

    tracymac7 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<