axiosソースシリーズ(3)---デフォルトの設定とキャンセルの要求

7824 ワード

前言
これは、多くの一般的な要求ライブラリです.プラットフォームにまたがって実現され、プロミセに戻ってチェーンで呼び出されます.ソースを完全に通過したら、自分の要求ライブラリに対する理解を高めることができます.
axiosソースシリーズ(一)---カタログ構造とツール関数axiosソースシリーズ(二)---アダプター内部axiosソースシリーズ(三)---標準設定とキャンセル要求axiosソースシリーズ(四)---AxiosとdispatchRequestとブロック
標準設定
axios/lib/defaults.js
このAxiosライブラリのデフォルトのパラメータ設定
var utils = require('./utils');
var normalizeHeaderName = require('./helpers/normalizeHeaderName');

var DEFAULT_CONTENT_TYPE = {
  'Content-Type': 'application/x-www-form-urlencoded'
};

function setContentTypeIfUnset(headers, value) {
  if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
    headers['Content-Type'] = value;
  }
}

function getDefaultAdapter() {
  var adapter;
  if (typeof XMLHttpRequest !== 'undefined') {
    // For browsers use XHR adapter
    adapter = require('./adapters/xhr');
  } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
    // For node use HTTP adapter
    adapter = require('./adapters/http');
  }
  return adapter;
}
ここには四つのことしかありません.
  • は、ツールライブラリと解析ヘッダ名関数
  • を導入する.
  • は、デフォルトContent-Typeがブラウザのデフォルトの符号化フォーマット
  • に設定する.
  • headers内の値が空のConteen-Type対応値を設定する方法を定義する
  • .
  • 宿主環境に応じて対応するadapters
  • を取得する.
    ソースのソースコードは以下の通りです.
    axios/lib/helpers/normalize Header Name.js
    フィルタによって、異なる大きさの文字を書くかどうかの等価要求ヘッダが得られます.はい、新しい要求ヘッダを設定して古い要求ヘッダを削除します.
    var utils = require('../utils');
    
    module.exports = function normalizeHeaderName(headers, normalizedName) {
      utils.forEach(headers, function processHeader(value, name) {
        if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
          headers[normalizedName] = value;
          delete headers[name];
        }
      });
    };
    これは露見の対象です.
    var defaults = {
      adapter: getDefaultAdapter(),
    
      transformRequest: [function transformRequest(data, headers) {
        normalizeHeaderName(headers, 'Accept');
        normalizeHeaderName(headers, 'Content-Type');
        if (utils.isFormData(data) ||
          utils.isArrayBuffer(data) ||
          utils.isBuffer(data) ||
          utils.isStream(data) ||
          utils.isFile(data) ||
          utils.isBlob(data)
        ) {
          return data;
        }
        if (utils.isArrayBufferView(data)) {
          return data.buffer;
        }
        if (utils.isURLSearchParams(data)) {
          setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
          return data.toString();
        }
        if (utils.isObject(data)) {
          setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
          return JSON.stringify(data);
        }
        return data;
      }],
    
      transformResponse: [function transformResponse(data) {
        /*eslint no-param-reassign:0*/
        if (typeof data === 'string') {
          try {
            data = JSON.parse(data);
          } catch (e) { /* Ignore */ }
        }
        return data;
      }],
    
      /**
       * A timeout in milliseconds to abort a request. If set to 0 (default) a
       * timeout is not created.
       */
      timeout: 0,
    
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
    
      maxContentLength: -1,
    
      validateStatus: function validateStatus(status) {
        return status >= 200 && status < 300;
      }
    };
    
    defaults.headers = {
      common: {
        'Accept': 'application/json, text/plain, */*'
      }
    };
    
    utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
      defaults.headers[method] = {};
    });
    
    utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
      defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
    });
    
    module.exports = defaults;
    いくつかのデフォルトの設定を提供します.
    設定
    作用
    アドホッター
    宿主環境対応のアダプター
    トランスフォームRequest
    変換関数を内蔵し、対応するフォーマットに従って要求を設定します.
    transform Resonse
    変換関数を内蔵しています.文字型であれば、逆の順序で並べ替えられます.
    タイムアウト
    タイムアウト時間
    xsrf Cookie Name
    xsrf tokenの値として使用するクッキーの名前
    xsrfHeader Name
    xsrf tokenの値を載せるHTTPヘッダの名前
    maxContintLength
    許可された応答内容の最大サイズを指定します.
    validateStatus
    所与のHTTP応答状態コードを内蔵することは、reolveまたはreject promiseの関数です.
    headers
    デフォルトの要求ヘッダ
    ['delete'、'get'、'head']
    関連する要求方式を定義するデフォルトの要求ヘッダ{}
    [post]、''put'、'patch']
    関連する要求方式のデフォルトの要求ヘッダを定義します.{Content-Type':'appication/x-wn-form-urlencoded'
    要求をキャンセルする
    axios/lib/cancel/Cancel.js
    /**
     * A `Cancel` is an object that is thrown when an operation is canceled.
     *
     * @class
     * @param {string=} message The message.
     */
    function Cancel(message) {
      this.message = message;
    }
    
    
    Cancel.prototype.toString = function toString() {
      return 'Cancel' + (this.message ? ': ' + this.message : '');
    };
    
    Cancel.prototype.__CANCEL__ = true;
    
    module.exports = Cancel;
    キャンセルの構造関数を作成し、ある要求をキャンセルし、キャンセル情報とマークを提供することを示します.
    axios/lib/cancel/Call Token.js
    var Cancel = require('./Cancel');
    
    /**
     * A `CancelToken` is an object that can be used to request cancellation of an operation.
     *
     * @class
     * @param {Function} executor The executor function.
     */
    function CancelToken(executor) {
      if (typeof executor !== 'function') {
        throw new TypeError('executor must be a function.');
      }
    
      var resolvePromise;
      this.promise = new Promise(function promiseExecutor(resolve) {
        resolvePromise = resolve;
      });
    
      var token = this;
      executor(function cancel(message) {
        if (token.reason) {
          // Cancellation has already been requested
          return;
        }
    
        token.reason = new Cancel(message);
        resolvePromise(token.reason);
      });
    }
    
    /**
     * Throws a `Cancel` if cancellation has been requested.
     */
    CancelToken.prototype.throwIfRequested = function throwIfRequested() {
      if (this.reason) {
        throw this.reason;
      }
    };
    
    /**
     * Returns an object that contains a new `CancelToken` and a function that, when called,
     * cancels the `CancelToken`.
     */
    CancelToken.source = function source() {
      var cancel;
      var token = new CancelToken(function executor(c) {
        cancel = c;
      });
      return {
        token: token,
        cancel: cancel
      };
    };
    
    module.exports = CancelToken;
    CancelTokenオブジェクトを作成し、要求をキャンセルするための動作:
  • は、新たなPromiseを定義し、状態を変更するトリガタイミングを外部
  • に伝達する.
  • は、着信するコールバック関数パラメータを実行する.
  • キャンセル要求がされた動作を示すreason属性が含まれている場合、中断動作
  • そうでなければ、新しいCancelオブジェクトを作成し、Promise状態を変更してオブジェクト
  • に戻る.
    プロトタイプthrowIfRequested方法は、インスタンスがキャンセルされた場合、キャンセル情報を直接に抛り出すことができる.
    コンストラクタ上でsource方法をバインディングし、呼び出した後、新しいCancelToken例とcancel方法を返すことができる.
    axios/lib/cancel/isCancel.js
    module.exports = function isCancel(value) {
      return !!(value && value.__CANCEL__);
    };
    __CANCEL__属性を持つかどうかによって、ある要求がキャンセルされたかどうかが分かります.
    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    
    axios.get('/user/12345', {
      cancelToken: source.token
    }).catch(function(thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
      } else {
         //     
      }
    });
    
    axios.post('/user/12345', {
      name: 'new name'
    }, {
      cancelToken: source.token
    })
    
    //     (message       )
    source.cancel('Operation canceled by the user.');
    または
    const CancelToken = axios.CancelToken;
    let cancel;
    
    axios.get('/user/12345', {
      cancelToken: new CancelToken(function executor(c) {
        // executor        cancel       
        cancel = c;
      })
    });
    
    // cancel the request
    cancel();