序文
前の記事では、学んだ、リッスンメソッドでカスタムthisを呼び出すことを学びました。".コールバック、コールバック実行の過程でコンテキスト、リクエスト、レスポンスを呼び出し、この記事では、何が行われているかを確認します。
Context
コンテキストのソースコードファイルはわずか252行で、非常にシンプルで、ファイル全体を見下ろす型判定、エラー処理に加えて、2つの場所のコアは、クッキーとデリゲートであり、この記事では、主にこの2つの部分について説明します。
cookies
まずソースコードを見てみましょう。
const COOKIES = Symbol('context#cookies');
const Cookies = require('cookies');
get cookies() {
if (!this[COOKIES]) {
this[COOKIES] = new Cookies(this.req, this.res, {
keys: this.app.keys,
secure: this.request.secure
});
}
return this[COOKIES];
},
set cookies(_cookies) {
this[COOKIES] = _cookies;
}
このコードは主にクッキーを get と set フォームにカプセル化し、またシンボルのユニークな特性によって単一のインスタンスを作成します。 また、Cookies オブジェクトを作成します。Cookies オブジェクトのソースコード:github.com/ScottHamper... は、その主な役割は req オブジェクトを通してヘッダの Cookie オブジェクトを取得することと、res オブジェクトにいくつかの変更を加えることです。主な役割は、reqオブジェクトを通してヘッダのクッキーオブジェクトを取得することと、resオブジェクトにいくつかの変更を加えることです。
delegate
/**
* Response delegation.
*/
delegate(proto, 'response')
.method('attachment')
.method('redirect')
.method('remove')
.method('vary')
.method('has')
.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')
.access('accept')
.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');
デリゲートの役割は、リクエストとレスポンスのメソッドとプロパティをContextに 委譲 することです。 まず、上のコードを縮小してみましょう:
delegate(proto, 'response')
.method('attachment')
.access('status')
.getter('headerSent')
主にメソッド、アクセス、ゲッターの3つのメソッドと呼ばれる、デリゲートが実際に何をするかを確認するには、デリゲートのソースコードを見つけるには、まず、メソッドを見てください。
function Delegator(proto, target) {
if (!(this instanceof Delegator)) return new Delegator(proto, target);
//
1. プロトとターゲットを取得する
this.proto = proto;
this.target = target;
//
2. メソッド、ゲッター、セッター、フルエント配列を作成する
this.methods = [];
this.getters = [];
this.setters = [];
this.fluents = [];
}
Delegator.prototype.method = function(name){
var proto = this.proto;
var target = this.target;
//
3. は、メソッド名プッシュメソッドの配列に渡される
this.methods.push(name);
// プロトがメソッドを呼び出すときに、直接プロトを呼び出すことができるように、プロトに着信メソッド名をマウントする。[target]
proto[name] = function(){
return this[target][name].apply(this[target], arguments);
};
return this;
};
デリゲータ関数とメソッドのメソッドを呼び出すと、主に以下の4つのことが行われます。
- 1. プロトとターゲットを取得
- 2. メソッド、ゲッター、セッター、フルエント配列を作成します。
- メソッド名をメソッド配列に入れます。
- プロトがメソッドを呼び出すときに、プロト[target]のメソッドを直接呼び出せるように、入力されたメソッド名をプロトにマウントします。
ゲッターとアクセスについてもう一度
Delegator.prototype.getter = function(name){
var proto = this.proto;
var target = this.target;
this.getters.push(name);
proto.__defineGetter__(name, function(){
return this[target][name];
});
return this;
};
Delegator.prototype.setter = function(name){
var proto = this.proto;
var target = this.target;
this.setters.push(name);
proto.__defineSetter__(name, function(val){
return this[target][name] = val;
});
return this;
};
Delegator.prototype.access = function(name){
return this.getter(name).setter(name);
};
ゲッターメソッドは、CTX上でリクエストのプロパティを直接呼び出す機能を実装しています。 セッターメソッドは、CTX上でリクエストのプロパティを変更する機能を実装しています。
koa は Delegator パターンを使って、リクエストとレスポンスで ctx がメソッドやプロパティを簡単に呼び出せるようにしています。
request&&response
要約
関連記事
ハンズオンで学ぶKoaソースコード - ディレクトリ構造 ハンズオンで学ぶKoaソースコード - ディレクトリ構造ハンズオンで学ぶKoaソースコード -ディレクトリ構造アプリケーション