如何设置超时以中止工厂或服务内的 $http.get() ?
How to set a timeout to abort an $http.get() inside a factory or service?
我在我的 工厂 中有以下方法 getData(url)
,它使用 $http.get(url)
从 URL
angular
.module('az-app')
.factory('WebServiceFactory', function ($http, $q) {
var WebServiceFactory = this;
WebServiceFactory.getData = function (url) {
var deferred = $q.defer();
$http.get(url)
.then(
function (response) {
deferred.resolve({
data: response
});
}, function (rejected) {
deferred.reject({
data: rejected
});
}
);
//Promise to be returned
return deferred.promise;
}
它工作正常,但我需要中止 http.get and/or 拒绝承诺,这样我就可以显示来自我的 控制器 的错误消息,它有这个方法:
var getSpecialties = function (type) {
doctorsCtrl.showLoading();
var url = "example.com";
WebServiceFactory.getData(url)
.then(
function (result) {
doctorsCtrl.hideLoading();
var specialtiesArray = result.data.data;
StorageFactory.specialties = specialtiesArray;
doctorsCtrl.specialties = StorageFactory.specialties
//I WANT TO TRIGGER THIS REJECTED FUNCTION when timeout time is finished
}, function (rejected) {
doctorsCtrl.hideLoading();
doctorsCtrl.showAlert();
}
);
}
服务 $http
在配置对象中接受 timeout
属性 来满足您的需求。看看 documentation,尤其是关于 config
对象的部分:
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
另外,请注意您正在以低效的方式使用承诺。以下是 promise 反模式:
WebServiceFactory.getData = function (url) {
var deferred = $q.defer();
$http.get(url)
.then(
function (response) {
deferred.resolve(...);
}, function (rejected) {
deferred.reject(...);
}
);
//Promise to be returned
return deferred.promise;
}
你可以简单地:
WebServiceFactory.getData = function (url) {
return $http.get(url);
}
如果超时时间为 3 秒,则为:
服务:
WebServiceFactory.getData = function (url) {
return $http.get(url, {timeout: 3000}); // <-- timeout applies ONLY for this call
}
控制器:
WebServiceFactory.getData(url).then(
function (result) {
doctorsCtrl.hideLoading();
doctorsCtrl.specialties = StorageFactory.specialties = result.data;
}, function (rejected) {
doctorsCtrl.hideLoading();
doctorsCtrl.showAlert();
}
);
另请注意,您在 成功 和 错误 的情况下都调用了 hideLoading
。您可以在链式 finally 处理程序中调用一次:
// ...
.finally(function () {
doctorsCtrl.hideLoading();
}
我在我的 工厂 中有以下方法 getData(url)
,它使用 $http.get(url)
从 URL
angular
.module('az-app')
.factory('WebServiceFactory', function ($http, $q) {
var WebServiceFactory = this;
WebServiceFactory.getData = function (url) {
var deferred = $q.defer();
$http.get(url)
.then(
function (response) {
deferred.resolve({
data: response
});
}, function (rejected) {
deferred.reject({
data: rejected
});
}
);
//Promise to be returned
return deferred.promise;
}
它工作正常,但我需要中止 http.get and/or 拒绝承诺,这样我就可以显示来自我的 控制器 的错误消息,它有这个方法:
var getSpecialties = function (type) {
doctorsCtrl.showLoading();
var url = "example.com";
WebServiceFactory.getData(url)
.then(
function (result) {
doctorsCtrl.hideLoading();
var specialtiesArray = result.data.data;
StorageFactory.specialties = specialtiesArray;
doctorsCtrl.specialties = StorageFactory.specialties
//I WANT TO TRIGGER THIS REJECTED FUNCTION when timeout time is finished
}, function (rejected) {
doctorsCtrl.hideLoading();
doctorsCtrl.showAlert();
}
);
}
服务 $http
在配置对象中接受 timeout
属性 来满足您的需求。看看 documentation,尤其是关于 config
对象的部分:
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
另外,请注意您正在以低效的方式使用承诺。以下是 promise 反模式:
WebServiceFactory.getData = function (url) { var deferred = $q.defer(); $http.get(url) .then( function (response) { deferred.resolve(...); }, function (rejected) { deferred.reject(...); } ); //Promise to be returned return deferred.promise; }
你可以简单地:
WebServiceFactory.getData = function (url) {
return $http.get(url);
}
如果超时时间为 3 秒,则为:
服务:
WebServiceFactory.getData = function (url) {
return $http.get(url, {timeout: 3000}); // <-- timeout applies ONLY for this call
}
控制器:
WebServiceFactory.getData(url).then(
function (result) {
doctorsCtrl.hideLoading();
doctorsCtrl.specialties = StorageFactory.specialties = result.data;
}, function (rejected) {
doctorsCtrl.hideLoading();
doctorsCtrl.showAlert();
}
);
另请注意,您在 成功 和 错误 的情况下都调用了 hideLoading
。您可以在链式 finally 处理程序中调用一次:
// ...
.finally(function () {
doctorsCtrl.hideLoading();
}