AngularJS: 为什么 .then() 不等待 promise 对象到达
AngularJS: Why is .then() not waiting for the promise object to arrive
我创建了以下 angular 服务以进行 API 调用。
(function (module) {
module.service('APIService',function ($http, $q) {
console.log("Reached APIService")
var deferred = $q.defer();
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
$http.get(requestURL).success(
function (data, status) {
deferred.resolve(data);
console.log("In service",status,data);
}).error(
function (data, status) {
deferred.reject(data);
console.log(status);
});
return deferred.promise;
};
this.postData = function (requestURL, requestObj) {
console.log("Reached APIService @POST", requestURL, requestObj);
$http.post(requestURL, requestObj).success(
function (data, status) {
deferred.resolve(data);
console.log(status);
}).error(
function (data, status) {
deferred.reject(data);
console.log(status);
});
return deferred.promise;
};
});
}(angular.module("MainApp")));
我已经将它注入我的两个控制器中。但是,我面临以下问题:
当我在第一个控制器中第一次调用它时,它工作正常并且 returns 得到了想要的结果。但是,当我在第二个控制器中按如下方式调用它时:
APIService.getData(Config + headerURL).then(function (response) {
console.log(Config + headerURL);
console.log("header response from API", response);
},function(error) {
console.log("API call for header data failed");
});
因为我的服务 returns 是一个承诺对象,所以我不希望 .then() 中的代码在服务数据到达之前工作。
但是,它在服务数据到达之前运行(不知道如何)。最奇怪的是我在.then()里面得到的response其实不是这个URL(Config+headerURL)的response,而是从不同的地方得到的response URL 之前使用相同的 APIService 服务在第一个 Controller 中调用。
特此通知:当前 URL 的实际响应确实会在稍后阶段到达。
我知道异步调用,我认为它在这种情况下有所作为,但我猜 .then() 在 Angular 中处理它。所以我很困惑这里的问题是什么。任何人都可以解释一下吗?
看来您必须在 $http 调用中明确禁用缓存。
$http.get({
url: requestURL,
cache: false
})
试试这个,您需要 return
到 http 结果。
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
return $http.get(requestURL) };
由于该服务是单例的,因此您只有一个延迟对象实例。
一旦解决,它将继续解决,所以下次调用 getData 时,它会立即 return。
您可以移动:
var deferred = $q.defer();
在您的 getData 和 postData 函数中。
或者您可以 return $http 创建的承诺。
当 $http
已经 return 是承诺时,您通过创建自己的承诺来使用 反模式 。
在此服务中完全摆脱 $q
并简单地 return $http
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
return $http.get(requestURL).then(function (response) {
return response.data;
console.log("In service", status, data);
}, function () {
// errror handling here
});
};
我创建了以下 angular 服务以进行 API 调用。
(function (module) {
module.service('APIService',function ($http, $q) {
console.log("Reached APIService")
var deferred = $q.defer();
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
$http.get(requestURL).success(
function (data, status) {
deferred.resolve(data);
console.log("In service",status,data);
}).error(
function (data, status) {
deferred.reject(data);
console.log(status);
});
return deferred.promise;
};
this.postData = function (requestURL, requestObj) {
console.log("Reached APIService @POST", requestURL, requestObj);
$http.post(requestURL, requestObj).success(
function (data, status) {
deferred.resolve(data);
console.log(status);
}).error(
function (data, status) {
deferred.reject(data);
console.log(status);
});
return deferred.promise;
};
});
}(angular.module("MainApp")));
我已经将它注入我的两个控制器中。但是,我面临以下问题:
当我在第一个控制器中第一次调用它时,它工作正常并且 returns 得到了想要的结果。但是,当我在第二个控制器中按如下方式调用它时:
APIService.getData(Config + headerURL).then(function (response) { console.log(Config + headerURL); console.log("header response from API", response); },function(error) { console.log("API call for header data failed"); });
因为我的服务 returns 是一个承诺对象,所以我不希望 .then() 中的代码在服务数据到达之前工作。 但是,它在服务数据到达之前运行(不知道如何)。最奇怪的是我在.then()里面得到的response其实不是这个URL(Config+headerURL)的response,而是从不同的地方得到的response URL 之前使用相同的 APIService 服务在第一个 Controller 中调用。
特此通知:当前 URL 的实际响应确实会在稍后阶段到达。
我知道异步调用,我认为它在这种情况下有所作为,但我猜 .then() 在 Angular 中处理它。所以我很困惑这里的问题是什么。任何人都可以解释一下吗?
看来您必须在 $http 调用中明确禁用缓存。
$http.get({
url: requestURL,
cache: false
})
试试这个,您需要 return
到 http 结果。
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
return $http.get(requestURL) };
由于该服务是单例的,因此您只有一个延迟对象实例。
一旦解决,它将继续解决,所以下次调用 getData 时,它会立即 return。
您可以移动:
var deferred = $q.defer();
在您的 getData 和 postData 函数中。
或者您可以 return $http 创建的承诺。
当 $http
已经 return 是承诺时,您通过创建自己的承诺来使用 反模式 。
在此服务中完全摆脱 $q
并简单地 return $http
this.getData = function (requestURL) {
console.log("Reached APIService @GET", requestURL);
return $http.get(requestURL).then(function (response) {
return response.data;
console.log("In service", status, data);
}, function () {
// errror handling here
});
};