国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

koa源碼閱讀之context.js/koa-convert/is-generator-functi

caikeal / 1545人閱讀

摘要:老伙計今天我們來講一下的還有一些自己寫的庫吧。我們常用來在中間件發(fā)出一些錯誤狀態(tài)碼。從而使得上級中間件可以這個錯誤從而響應默認的一個錯誤處理如果不是實例。看完全文都是好樣的源碼鏈接文檔鏈接

hey 老伙計 今天我們來講一下koa的context.js還有一些tj自己寫的庫吧。 context.js
"use strict";
const createError = require("http-errors");
const httpAssert = require("http-assert");
const delegate = require("delegates");
const statuses = require("statuses");

const proto = module.exports = {

    //前面文章有講過這個了,這里不描述了
  inspect() {
    if (this === proto) return this;
    return this.toJSON();
  },

  toJSON() {
    return {
      request: this.request.toJSON(),//實際上調(diào)用request.js的toJSON(下同)
      response: this.response.toJSON(),
      app: this.app.toJSON(),
      originalUrl: this.originalUrl,
      req: "",
      res: "",
      socket: ""
    };
  },

  /**
   * Similar to .throw(), adds assertion.
   *
   *    this.assert(this.user, 401, "Please login!");
   *
   * See: https://github.com/jshttp/http-assert
   *
   * @param {Mixed} test
   * @param {Number} status
   * @param {String} message
   * @api public
   */

  assert: httpAssert,

  /**
   * Throw an error with `msg` and optional `status`
   * defaulting to 500. Note that these are user-level
   * errors, and the message may be exposed to the client.
   *
   *    this.throw(403)
   *    this.throw("name required", 400)
   *    this.throw(400, "name required")
   *    this.throw("something exploded")
   *    this.throw(new Error("invalid"), 400);
   *    this.throw(400, new Error("invalid"));
   *
   * See: https://github.com/jshttp/http-errors
   *
   * @param {String|Number|Error} err, msg or status
   * @param {String|Number|Error} [err, msg or status]
   * @param {Object} [props]
   * @api public
   */
    //throw方法。上面是使用的方法。我們 常用來在中間件throw發(fā)出一些錯誤狀態(tài)碼。
    //從而使得上級中間件可以try catch這個錯誤從而響應
    //createError([status], [message], [properties])
    //properties - custom properties to attach to the object
  throw(...args) {
    throw createError(...args);
  },
    //默認的一個錯誤處理
  onerror(err) {
    // don"t do anything if there is no error.
    // this allows you to pass `this.onerror`
    // to node-style callbacks.
    if (null == err) return;
    // 如果error不是Error實例。此時生成一個錯誤實例給下文處理
    if (!(err instanceof Error)) err = new Error(`non-error thrown: ${err}`);

    let headerSent = false;
    //當然需要可寫且沒有被發(fā)送
    if (this.headerSent || !this.writable) {
      headerSent = err.headerSent = true;
    }

    //觸發(fā)事件
    this.app.emit("error", err, this);

    //發(fā)送了肯定啥都不能干了
    if (headerSent) {
      return;
    }

    const { res } = this;
    //解構一下獲得response
    
    //兼容咯
    //首次清除所有的headers
    if (typeof res.getHeaderNames === "function") {
      res.getHeaderNames().forEach(name => res.removeHeader(name));
    } else {
      res._headers = {}; // Node < 7.7
    }

    // 然后設置為錯誤的headers標識
    this.set(err.headers);

    //強制text/plain
    this.type = "text";

    // 支持ENOENT 
    if ("ENOENT" == err.code) err.status = 404;

    // 默認轉(zhuǎn)換成500狀態(tài)碼
    if ("number" != typeof err.status || !statuses[err.status]) err.status = 500;

    //響應
    const code = statuses[err.status];
    const msg = err.expose ? err.message : code;
    this.status = err.status;
    this.length = Buffer.byteLength(msg);
    this.res.end(msg);
    //跟原生的一樣嘛。
    //給我們一個提示。我們要使一個連接關閉。那么ctx.res.end(msg);
  }
};

/**
 * Response delegation.
 */
//委托到這個上下文對象里
//委托方法 與屬性的getter或者setter
delegate(proto, "response")
  .method("attachment")
  .method("redirect")
  .method("remove")
  .method("vary")
  .method("set")
  .method("append")
  .method("flushHeaders")
  .access("status")
  .access("message")
  .access("body")
  .access("length")
  .access("type")
  .access("lastModified")
  .access("etag")
  .getter("headerSent")
  .getter("writable");

/**
 * Request delegation.
 */

delegate(proto, "request")
  .method("acceptsLanguages")
  .method("acceptsEncodings")
  .method("acceptsCharsets")
  .method("accepts")
  .method("get")
  .method("is")
  .access("querystring")
  .access("idempotent")
  .access("socket")
  .access("search")
  .access("method")
  .access("query")
  .access("path")
  .access("url")
  .getter("origin")
  .getter("href")
  .getter("subdomains")
  .getter("protocol")
  .getter("host")
  .getter("hostname")
  .getter("URL")
  .getter("header")
  .getter("headers")
  .getter("secure")
  .getter("stale")
  .getter("fresh")
  .getter("ips")
  .getter("ip");

因為下一個篇幅準備將最重要的application.js
所以這個接下來準備說幾個引入的庫源碼

koa convert 用于什么?用于將koa1的中間件轉(zhuǎn)化為promise 看到co就應該有這么個想法了= =
"use strict"

const co = require("co")
//引入co
const compose = require("koa-compose")

module.exports = convert

function convert (mw) {
    //進行判斷
  if (typeof mw !== "function") {
    throw new TypeError("middleware must be a function")
  }
  if (mw.constructor.name !== "GeneratorFunction") {
    // assume it"s Promise-based middleware
    return mw
  }
  const converted = function (ctx, next) {
    return co.call(ctx, mw.call(ctx, createGenerator(next)))
  }
  converted._name = mw._name || mw.name
  return converted
}

function * createGenerator (next) {
  return yield next()
}

// convert.compose(mw, mw, mw)
// convert.compose([mw, mw, mw])
// koa-compose 日后再說嘻嘻^v^
convert.compose = function (arr) {
  if (!Array.isArray(arr)) {
    arr = Array.from(arguments)
  }
  return compose(arr.map(convert))
}
//我的天啊。這個瘋子還支持回退
//回退方法很是精妙啊
convert.back = function (mw) {
  if (typeof mw !== "function") {
    throw new TypeError("middleware must be a function")
  }
  if (mw.constructor.name === "GeneratorFunction") {
    // assume it"s generator middleware
    return mw
  }
  const converted = function * (next) {
    let ctx = this
    let called = false
    // no need try...catch here, it"s ok even `mw()` throw exception
    yield Promise.resolve(mw(ctx, function () {
        //使得next僅僅被調(diào)用一次
      if (called) {
        // guard against multiple next() calls
        // https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36
        return Promise.reject(new Error("next() called multiple times"))
      }
      called = true
      return co.call(ctx, next)
    }))
  }
  converted._name = mw._name || mw.name
  return converted
}
is-generator-function
"use strict";
//減少查找引用,常見的優(yōu)化方法
var toStr = Object.prototype.toString;
var fnToStr = Function.prototype.toString;
//這個正則匹配function *但是好像有點bug
//* function(){}也會受到判定true
var isFnRegex = /^s*(?:function)?*/;

var hasToStringTag = typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol";
var getProto = Object.getPrototypeOf;
var getGeneratorFunc = function () { // eslint-disable-line consistent-return
    if (!hasToStringTag) {
        return false;
    }
    try {
        return Function("return function*() {}")();
    } catch (e) {
    }
};
var generatorFunc = getGeneratorFunc();
var GeneratorFunction = generatorFunc ? getProto(generatorFunc) : {};

//主要從三點看。
//一點是function toString
//一點是[object GeneratorFunction] Object toString
//一點是從原型看(內(nèi)部[[Prototype]]屬性的值)
module.exports = function isGeneratorFunction(fn) {
    if (typeof fn !== "function") {
        return false;
    }
    if (isFnRegex.test(fnToStr.call(fn))) {
        return true;
    }
    if (!hasToStringTag) {
        var str = toStr.call(fn);
        return str === "[object GeneratorFunction]";
    }
    return getProto(fn) === GeneratorFunction;
};

這次寫的好粗糙啊= =
希望在結尾部分能寫好。
sry sry sry

看完全文都是好樣的!!

koa源碼鏈接

文檔api鏈接

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/85107.html

相關文章

  • koa源碼閱讀目錄結構與輔助庫相關

    摘要:從一個對象里面提取需要的屬性這篇文章一直想寫了還想起那一夜我看到白天的代碼,實在太美了。 koa源碼lib主要文件有 application.js context.js request.js response.js application.js koa主要的邏輯處理代碼整個koa的處理 context.js 將req,res方法 掛載在這,生成ctx上下文對象 requests....

    sherlock221 評論0 收藏0
  • 超輕量級web框架koa源碼閱讀

    摘要:是一個非常輕量的框架,里面除了和之外什么都沒有,甚至連最基本的功能都需要通過安裝其他中間件來實現(xiàn)。而的源碼同樣很簡潔,基礎代碼只有不到行,非常適合閱讀學習。的源碼直接從獲取,本文采用目前最新的版本。 koa是一個非常輕量的web框架,里面除了ctx和middleware之外什么都沒有,甚至連最基本的router功能都需要通過安裝其他中間件來實現(xiàn)。不過雖然簡單,但是它卻非常強大,僅僅依靠...

    inapt 評論0 收藏0
  • Koa源碼閱讀筆記(2) -- compose

    摘要:于是抱著知其然也要知其所以然的想法,開始閱讀的源代碼。問題讀源代碼時,自然是帶著諸多問題的。源代碼如下在被處理完后,每當有新請求,便會調(diào)用,去處理請求。接下來會繼續(xù)寫一些閱讀筆記,因為看的源代碼確實是獲益匪淺。 本筆記共四篇Koa源碼閱讀筆記(1) -- coKoa源碼閱讀筆記(2) -- composeKoa源碼閱讀筆記(3) -- 服務器の啟動與請求處理Koa源碼閱讀筆記(4) -...

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

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

    ityouknow 評論0 收藏0
  • 如何閱讀源碼--Koa為例

    摘要:最近一年零零散散看了不少開源項目的源碼多少也有點心得這里想通過這篇文章總結一下這里以為例前段時間其實看過的源碼但是發(fā)現(xiàn)理解的有點偏差所以重新過一遍不得不說閱讀的代碼真的收獲很大沒啥奇技淫巧代碼優(yōu)雅設計極好注釋什么的就更不用說了總之還是推薦把 最近一年零零散散看了不少開源項目的源碼, 多少也有點心得, 這里想通過這篇文章總結一下, 這里以Koa為例, 前段時間其實看過Koa的源碼, 但是...

    zhoutk 評論0 收藏0

發(fā)表評論

0條評論

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