axios:スクリーンの設計と実現

3347 ワード

概要
AxiosはPromiseベースのHTTPクライアントであり、ブラウザとNode.js環境をサポートしています。これは優秀なHTTPクライアントであり、大量のWebプロジェクトに広く応用されています。具体的な紹介は公式文書です。
ほとんどのアプリケーションにとって、ajax要求を一括処理するシーンがあります。この問題をより良く解決するために、スクリーンショットが生まれました。Axiosでは、要求と応答を別々に処理するためにブロッカと応答ブロックを要求して提供され、それらの役割は以下の通りである。
  • は、要求ヘッダにtokenフィールドを追加するなど、送信を要求する前に、ある動作を一括して実行するブロックを要求する。
  • 応答ブロック:このようなスクリーンセーバの役割は、応答状態コードが401であることを発見したときなど、サーバ応答を受信した後に、いくつかの動作を一括して実行することである。
  • 続いて、本文はaxiosのソースコードを通してブロックがどのように設計されて実現されるかを述べます。
    設計と実現
    ジョブの登録
    まず以下のコードを例にとって、米国を通じて(通って)スクリーンセーバーに方法を登録します。
    // request interceptor
    axios.interceptors.request.use(
      config => {
        console.log('config', config);
        return config;
      },
      err => Promise.reject(err),
    );
    
    // response interceptor
    axios.interceptors.response.use(response => {
      console.log('response', response);
      return response;
    });
    
    // axios/lib/core/InterceptorManager.js
    //           use            
    InterceptorManager.prototype.use = function use(fulfilled, rejected) {
      this.handlers.push({
        fulfilled: fulfilled,
        rejected: rejected
      });
      return this.handlers.length - 1;
    };
    
    
    任務の編成
    //   lib/axios.js(    )          
    function createInstance(defaultConfig) {
      var context = new Axios(defaultConfig);
    
      // REVIEW[epic=interceptors,seq=0]  axios     request  ,  axios({option})         request  
      var instance = bind(Axios.prototype.request, context);
    
      // Copy axios.prototype to instance
      utils.extend(instance, Axios.prototype, context);
    
      // Copy context to instance
      utils.extend(instance, context);
    
      return instance;
    }
    //     Axios.prototype.request
    Axios.prototype.request = function request(config) {
        // ...       
      // Hook up interceptors middleware
      // REVIEW[epic=interceptors,seq=2] dispatchRequest      axios ,        
      var chain = [dispatchRequest, undefined];
      var promise = Promise.resolve(config);
    
      // REVIEW[epic=interceptors,seq=4]               request  
      this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
      });
    
      // REVIEW[epic=interceptors,seq=5]               response  
      this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
        chain.push(interceptor.fulfilled, interceptor.rejected);
      });
      //          ,         chain         :
      // [ ...requestInterceptor, dispatchRequest,undefined, ...responseInterceptor ]
      //               
    
      while (chain.length) {
        //           (fulfilled, rejected)         shift2 
        promise = promise.then(chain.shift(), chain.shift());
      }
      return promise;
    };
    
    異なる位置からタスクリストにタスクを追加することで、タスクの編成が実現し、request Interceptor=>Request=>reponse Interceptorの順に実行する目的が達成されていることが分かります。
    タスクのスケジュール
    タスクのスケジュールは主に上のrequest関数の中のこの行を見ます。
      var promise = Promise.resolve(config);
      while (chain.length) {
        //           (fulfilled, rejected)         shift2 
        promise = promise.then(chain.shift(), chain.shift());
      }
    登録順に順次実行され、ジョブごとにconfigに戻ります。
    おわりに
    今回のソースコードを読んでいるとき、明らかにこの前の積み重ねのために、ソースコードを読むことはそんなに難しくなくなりました。しかし、文書を書く時、どうやってもっとはっきりと表現するか、問題があります。したがって、オンラインの既存の文書を参考にして、タスク登録=>タスク編成=>タスクスケジュールを使用して、タスクを視点として解析する方式でコードを説明します。