경로 전환 시 자원 약속을 취소하는 방법을 Angularjs
Angularjs에 발을 담그는 중이야저는 약속과 관련이 있다고 생각하는 문제가 있습니다.
예를 들어, 'A' 루트를 로드하면 A의 컨트롤러를 통해 여러 개의 Ajax 요구가 발생합니다.
allSites = AllSites.query({ id:categoryID });
allSites.$promise.then(function(allSites){
//add stuff to the scope and does other things
//(including making another ajax request)
});
다음으로 컨트롤러 경유로 독자적인 API 요구를 하는 루트 'B'가 있습니다.
$scope.categories = Category.query();
A번 노선에서 현재 사용하고 있는 공장 서비스는 다음과 같습니다.
.factory('AllSites',function($resource){
return $resource('api/categorySites/:id');
});
'되기 전에 될 때까지 ()그에서 'A에서 'A'에 있는 될 때까지 ).이 완료될 때까지 기다립니다(실제로 query() 요구가 이루어지지만, 그 시점에서 A에서 온 것이 처리되지 않는 한 해결되지 않습니다..then()지금 다른 길을 가고 있기 때문에 필요없지만, 계속 일어나고 있습니다.
devtools 타임라인에서 볼 수 있듯이 녹색 선은 'B' 경로로 전환한 시기를 나타냅니다.루트 'B'에 대한 요구는 위의 두 가지 요구(통상 매우 빠른 요구)가 해결될 때까지 해결되지 않았습니다.(이 시점에서 뷰를 유저로서 사용할 수 있습니다).그 후 루트 A에서 더 많은 약속이 해결됩니다.

저는 답을 찾기 위해 모든 곳을 찾아봤지만, 약속이 해결될 때까지 경로 로딩을 "지연"하려는 사람들만 찾을 수 있습니다.하지만 제 경우엔 거의 그 반대입니다.나는 그 요구를 바꿀 때 없애고 싶다.
여기 또 다른 누군가가 같은 답을 하지 못한 질문을 하고 있습니다.Angularjs 리소스 약속 거부
어떤 도움이라도 감사합니다.
선,, 는는이을 first first first를 사용해야겠다고 했습니다.$http어떤 해결책도 찾을 수 없었기 때문에$resource나 혼자서는 작동시킬 수 없었다.
http://www.bennadel.com/blog/2616-aborting-ajax-requests-using-http-and-angularjs.htm에 있는 가이드를 사용하여 @Sid의 답변을 바탕으로 공장을 다음과 같이 변화시켰습니다.
.factory('AllSites',function($http,$q){
function getSites(categoryID) {
// The timeout property of the http request takes a deferred value
// that will abort the underying AJAX request if / when the deferred
// value is resolved.
var deferredAbort = $q.defer();
// Initiate the AJAX request.
var request = $http({
method: 'get',
url: 'api/categorySites/'+categoryID,
timeout: deferredAbort.promise
});
// Rather than returning the http-promise object, we want to pipe it
// through another promise so that we can "unwrap" the response
// without letting the http-transport mechansim leak out of the
// service layer.
var promise = request.then(
function( response ) {
return( response.data );
},
function() {
return( $q.reject( 'Something went wrong' ) );
}
);
// Now that we have the promise that we're going to return to the
// calling context, let's augment it with the abort method. Since
// the $http service uses a deferred value for the timeout, then
// all we have to do here is resolve the value and AngularJS will
// abort the underlying AJAX request.
promise.abort = function() {
deferredAbort.resolve();
};
// Since we're creating functions and passing them out of scope,
// we're creating object references that may be hard to garbage
// collect. As such, we can perform some clean-up once we know
// that the requests has finished.
promise.finally(
function() {
promise.abort = angular.noop;
deferredAbort = request = promise = null;
}
);
return( promise );
}
// Return the public API.
return({
getSites: getSites
});
});
다음으로 컨트롤러(문제의 루트 'A'):
var allSitesPromise = AllSites.getSites(categoryID);
$scope.$on('$destroy',function(){
allSitesPromise.abort();
});
allSitesPromise.then(function(allSites){
// do stuff here with the result
}
공장이 그렇게 지저분하지 않았으면 좋겠지만, 내가 구할 수 있는 걸 가져가겠어요.하지만, 이제 다른 관련 문제가 생겼습니다. 이 문제는 약속은 취소되었지만, 다음 조치는 여전히 지연되고 있습니다.정답이 있으면 거기에 올리면 돼요.
"$resource 요청을 취소하는 방법"이라는 답변과 유사한 질문이 있습니다.
이 질문에는 정확하게 대응하지 않지만 루트 전환 시 자원 요구를 취소할 수 있는 모든 요소가 제공됩니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Cancel resource</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-resource.js"></script>
<script>
angular.module("app", ["ngResource"]).
factory(
"services",
["$resource", function($resource)
{
function resolveAction(resolve)
{
if (this.params)
{
this.timeout = this.params.timeout;
this.params.timeout = null;
}
this.then = null;
resolve(this);
}
return $resource(
"http://md5.jsontest.com/",
{},
{
MD5:
{
method: "GET",
params: { text: null },
then: resolveAction
},
});
}]).
controller(
"Test",
["services", "$q", "$timeout", function(services, $q, $timeout)
{
this.value = "Sample text";
this.requestTimeout = 100;
this.call = function()
{
var self = this;
self.result = services.MD5(
{
text: self.value,
timeout: $q(function(resolve)
{
$timeout(resolve, self.requestTimeout);
})
});
}
}]);
</script>
</head>
<body ng-app="app" ng-controller="Test as test">
<label>Text: <input type="text" ng-model="test.value" /></label><br/>
<label>Timeout: <input type="text" ng-model="test.requestTimeout" /></label><br/>
<input type="button" value="call" ng-click="test.call()"/>
<div ng-bind="test.result.md5"></div>
</body>
</html>
구조
- $resource는 액션 정의, 요청 매개 변수 및 데이터를 병합하여 $syslog 요청에 대한 구성 매개 변수를 구축합니다.
- $syslog 요구에 전달된 config 파라미터는 약속과 같은 오브젝트로 취급되기 때문에 설정을 초기화하는 함수를 포함할 수 있습니다.
- 액션의 함수는 파라미터에서 Configuration으로 타임아웃 약속을 전달할 수 있습니다.
자세한 내용은 "Cancel Angularjs 리소스 요청 취소"를 참조하십시오.
루트 변경 시(또는 UI 라우터를 사용하는 경우 상태 변경 시) 요구를 중단하겠다는 약속을 해결할 수 있습니다.
실현하기 가장 쉬운 일은 아닐지 몰라도 효과가 있을 것 같다.
$q.reject()와의 약속을 취소합니다.이 방법이 더 간단하다고 생각합니다.
[사이트 서비스(Sites Services)]에서 선택합니다.js:
;(() => {
app.services('SitesServices', sitesServices)
sitesServices.$inject = ['$http', '$q']
function sitesServices($http, $q) {
var sitesPromise = $q.defer()
this.getSites = () => {
var url = 'api/sites'
sitesPromise.reject()
sitesPromise = $q.defer()
$http.get(url)
.success(sitesPromise.resolve)
.error(sitesPromise.reject)
return sitesPromise.promise
}
}
})()
SitesController.js의 경우:
;(() => {
app.controller('SitesController', sitesControler)
sitesControler.$inject = ['$scope', 'SitesServices']
function sitesControler($scope, SitesServices) {
$scope.sites = []
$scope.getSites = () => {
SitesServices.getSites().then(sites => {
$scope.sites = sites
})
}
}
})()
다음 문서 확인$resource나는 이 작은 아름다움의 연결고리를 찾았다.https://docs.angularjs.org/api/ng/service/$http#usage
timeout – {number|Promise}: 밀리초 단위의 타임아웃 또는 해결되면 요구를 중단하는 약속.
나는 그것을 어느 정도 성공적으로 사용해 왔다.약간 이런 느낌이에요.
export default function MyService($q, $http) {
"ngInject";
var service = {
getStuff: getStuff,
};
let _cancelGetStuff = angular.noop;
return service;
function getStuff(args) {
_cancelGetStuff(); // cancel any previous request that might be ongoing.
let canceller = $q( resolve => { _cancelGetStuff = resolve; });
return $http({
method: "GET",
url: <MYURL>
params: args,
timeout: canceller
}).then(successCB, errorCB);
function successCB (response) {
return response.data;
}
function errorCB (error) {
return $q.reject(error.data);
}
}
}
명심해
- 마지막 요청의 결과만 원하는 것으로 가정합니다.
- 취소된 요청이 계속 호출됩니다.
successCB하지만response이undefined. - 또한 errorCB를 호출할 수도 있습니다.
error.status될 것이다-1요청 시간이 초과된 경우처럼요.
언급URL : https://stackoverflow.com/questions/24440177/angularjs-how-to-cancel-resource-promise-when-switching-routes
'sourcecode' 카테고리의 다른 글
| 봄의 @Configuration과 @Component의 차이점은 무엇입니까? (0) | 2023.02.27 |
|---|---|
| 정밀도와 스케일의 차이는 무엇입니까? (0) | 2023.02.27 |
| eslint: 반복기(react/jsx-key) 요소에 대한 "키" 프로펠러가 없습니다. (0) | 2023.02.27 |
| Jest에서 TypeScript를 사용한 모의 의존 관계 (0) | 2023.02.27 |
| 행이 다른 트랜잭션에 의해 업데이트 또는 삭제되었습니다(또는 저장되지 않은 값 매핑이 잘못되었습니다). (0) | 2023.02.27 |