2016-08-20 1 views
2

Ich lernte heute eckige Abfangjäger. Ich habe ein paar Proben gemacht, um das Konzept besser zu verstehen. Hier ist eine kleine Probe.Wie kantige Abfangjäger arbeiten?

var app = angular.module("myApp", []); 
 

 
app.factory("timestampMaker", [ 
 
    function() { 
 
    var timestampMaker = { 
 
     request: function(config) { 
 
     console.log(config); 
 
     config.requestTimestamp = new Date().getTime(); 
 
     return config; 
 
     }, 
 
     response: function(response) { 
 

 
     response.config.responseTimestamp = new Date().getTime(); 
 
     return response; 
 
     } 
 
    }; 
 
    return timestampMaker; 
 
    } 
 
]); 
 

 
app.config(['$httpProvider', 
 
    function($httpProvider) { 
 
    $httpProvider.interceptors.push('timestampMaker'); 
 
    } 
 
]); 
 

 
app.run(function($http) { 
 
    $http.get('https://api.github.com/users/naorye/repos').then(function(response) { 
 
    console.log(response); 
 
    var time = response.config.responseTimestamp - response.config.requestTimestamp; 
 
    console.log("The request took" + (time/1000) + "seconds") 
 
    }); 
 
});
<html ng-app="myApp"> 
 

 
<head> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
</head> 
 

 
</html>

Wenn ich console.log(config) innen Anforderungsfunktion mache, hier ist die Ausgabe auf der Konsole. enter image description here

ich immer bin nicht wie responseTimestamp in dem Config-Objekt der Anfrage angezeigt, in dem als innerhalb Antwortfunktion definiert

Antwort

0

Hinweis Ich verwenden Quellcode für 1.2.x, die die in der Frage hinzugefügt ist.

$httpProvider ist ein Anbieter, der Ihnen $http Service gibt.

Als Provider, in Config-Zeit legt ein öffentliches Array - dort fügen Sie einfach alle Zeichenfolgen aus Services Namen, die Sie in Ihre Antwort/Anfragen injiziert werden wollte.

Das ist, was Sie hier tun

app.config(['$httpProvider', 
    function($httpProvider) { 
    $httpProvider.interceptors.push('timestampMaker'); 
    } 
]); 

und es kann nur in Config-Zeit durchgeführt werden, da pro docs Anbieter können vor der Anwendung konfiguriert werden beginnt

Sie können die freiliegenden Array in der sehen source code in Zeile 159

var responseInterceptorFactories = this.responseInterceptors = []; 

Wenn Sie verlangen den $http Service, es in die Injektion Service/Controller, $get Funktion wird ausgeführt. In dieser Funktion wird Ihr Array von Abfangraketen iteriert, wie Sie in source code in Zeile 179

var reversedInterceptors = []; 
    forEach(responseInterceptorFactories, function(interceptorFactory, index) { 
     var responseFn = isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory); 

     /** 
     * Response interceptors go before "around" interceptors (no real reason, just 
     * had to pick one.) But they are already reversed, so we can't use unshift, hence 
     * the splice. 
     */ 
     reversedInterceptors.splice(index, 0, { 
     response: function(response) { 
      return responseFn($q.when(response)); 
     }, 
     responseError: function(response) { 
      return responseFn($q.reject(response)); 
     } 
     }); 
    }); 

Per Konvention sehen können, sie die Reihenfolge umkehren. Sie können sehen, dass mit der Zeichenfolge, erhalten sie einen Verweis auf die Funktion mit $injector.get oder $injector.invoke, und mit $q.when() können wir sie in die Versprechen Kette vorstellen, auch wenn sie synchronen Code sind - Siehe diese Can I use $q.all in AngularJS with a function that does not return a .promise?, wenn Sie nicht sicher sind, was ich meinte über $q.when()

Bisher haben wir ein Array mit Funktionen, die alle versprechen sind (Danke an $q.when()). Wenn Sie Daten thorught $http wie diese

$http.get('https://api.github.com/users/naorye/repos').then(function(response) { 
    console.log(response); 
    var time = response.config.responseTimestamp - response.config.requestTimestamp; 
    console.log("The request took" + (time/1000) + "seconds") 
    }); 

verlangen, auch wenn Sie die .get(), haben nur ein shorcut für alle die gleiche Funktionalität, die here

Im Code ist der relevante Teil dieses ist:

Zuerst wird ein Kettenarray mit zwei Werten erstellt: eine innere Funktion, die für unseren Zweck nicht wichtig ist (aber sie gibt ein Versprechen zurück - das ist wichtig), undefinierter Wert.

Unser Array mit Interceptors wird iteriert und Request Interceptors werden am Anfang (vor der Anfrage) und am Ende der Anfrage hinzugefügt. Gefallen Sie diese

function serverRequest { 
     // some code 
    }; 
    var chain = [serverRequest, undefined]; 
    var promise = $q.when(config); 

    // apply interceptors 
    forEach(reversedInterceptors, function(interceptor) { 
     if (interceptor.request || interceptor.requestError) { 
     chain.unshift(interceptor.request, interceptor.requestError); 
     } 
     if (interceptor.response || interceptor.responseError) { 
     chain.push(interceptor.response, interceptor.responseError); 
     } 
    }); 

dann, mit der Kette vollständig (erinnert unser Angebot an Abfangjäger war voller Versprechen), der Code durch sie und fügt hinzu, alle von ihnen .then() verwenden, so dass sie alle in der Kette ausgeführt werden, folgende Versprechen Chaining (man kann, dass google)

while(chain.length) { 
     var thenFn = chain.shift(); 
     var rejectFn = chain.shift(); 

     promise = promise.then(thenFn, rejectFn); 
    } 

Schließlich Sie der Rückruf in success hinzufügen und error sind ganz am Ende der Kette und das Versprechen zurückgeführt wird

promise.success = function(fn) { 
    promise.then(function(response) { 
    fn(response.data, response.status, response.headers, config); 
    }); 
    return promise; 
}; 

promise.error = function(fn) { 
    promise.then(null, function(response) { 
    fn(response.data, response.status, response.headers, config); 
    }); 
    return promise; 
}; 

return promise; 
hinzugefügt

Das einzige, was ich nicht sicher bin, ist die Verwendung von undefined in der Kette Array

Zusammenfassung

Sie den Namen für Ihre Dienste hinzufügen, $HttpProvider verwendet $invoke Service, sie zu erhalten und fügt sie in die Versprechenskette, die $q.when() verwendet und ein Versprechen zurückbringt. Am Ende werden Ihre Rückrufe für eine spezifische $http Anfrage hinzugefügt

Verwandte Themen