AngularJS中$http的竞争条件
Race condition with $http in AngularJS
我有以下服务:
app.factory('ParserWebService', function($http, $q, $timeout){
ParserWebService.getParserPfList = function() {
var pfData = $q.defer();
var pfList = [];
$http.get("https://myurl/parserpf")
.then(function(response) {
var reponseDataJSON = JSON.parse(response.data);
for (var el in reponseDataJSON) {
if (reponseDataJSON[el].pf.length > 0) { // Check for non-empty string
pfList.push(reponseDataJSON[el]);
}
}
console.log("http GET SUCCESS");
console.log("pfList.length: " + pfList.length);
})
.catch(function(response) {
console.error('GET error', response.status, response.data);
})
console.log(pfList[0]);
$timeout(function(){
pfData.resolve(pfList);
},1000);
console.log("pfList.length: " + pfList.length);
console.log("pfData.promise.length: " + pfData.promise.length);
return pfData.promise;
}
return ParserWebService;
});
当我调用它时,我首先得到错误,因为在返回之前,服务根据控制台打印输出不返回任何内容(请参阅中的)。只有在那之后,我才在控制台上看到$http成功的打印输出,pfList.lenght是109(见下文)。
pfList.length: 0 <------------------
pfData.promise.length: undefined <----------------
mopidId = 0, id = null
angular.js:11607 TypeError: Cannot read property 'id' of undefined
at new <anonymous> (controllers.js:32)
at Object.e [as invoke] (angular.js:4185)
at $get.w.instance (angular.js:8454)
at angular.js:7700
at s (angular.js:331)
at A (angular.js:7699)
at g (angular.js:7078)
at g (angular.js:7081)
at g (angular.js:7081)
at angular.js:6957(anonymous function) @ angular.js:11607$get @ angular.js:8557$get.l.$apply @ angular.js:14502(anonymous function) @ angular.js:1448e @ angular.js:4185d @ angular.js:1446tc @ angular.js:1466Jd @ angular.js:1360(anonymous function) @ angular.js:26176m.Callbacks.j @ jquery.js:3148m.Callbacks.k.fireWith @ jquery.js:3260m.extend.ready @ jquery.js:3472J @ jquery.js:3503
models.js:599 http GET SUCCESS <---------------
models.js:600 pfList.length: 109 <---------------
这似乎是一种种族状况。为什么会发生这种情况,以及如何解决?谢谢
我认为你让事情变得不必要的复杂。
$http
本身返回一个promise,所以只需从函数中返回它,就不需要$q
或奇怪的超时。见下文
app.factory('ParserWebService', function($http){
ParserWebService.pfList=[];
ParserWebService.getParserPfList = function() {
return $http.get("https://myurl/parserpf")
.then(function(response) {
var reponseDataJSON = JSON.parse(response.data);
for (var el in reponseDataJSON) {
if (reponseDataJSON[el].pf.length > 0) { // Check for non-empty string
ParserWebService.pfList.push(reponseDataJSON[el]);
}
}
})
.catch(function(response) {
console.error('GET error', response.status, response.data);
})
}
return ParserWebService;
});
第一个console.log
没有数据的原因是它不在then
块中,所以它在$http
调用有机会完成之前执行。
如果你使用上面的代码来链接事件,你会像一样使用它
ParserWebService.getParserPfList.then(function(){
console.log("All the data is here: ",ParserWebService.pfList);
})
如果你确定要让承诺返回函数中的数据,你可以这样修改你的代码:
ParserWebService.getParserPfList = function() {
var pfData = $q.defer();
var pfList = [];
$http.get("https://myurl/parserpf")
.then(function(response) {
var reponseDataJSON = JSON.parse(response.data);
for (var el in reponseDataJSON) {
if (reponseDataJSON[el].pf.length > 0) { // Check for non-empty string
pfList.push(reponseDataJSON[el]);
}
}
pfData.resolve(pfList);
})
.catch(function(response) {
console.error('GET error', response.status, response.data);
pfData.reject();
})
return pfData.promise;
}
最后注意:如果您为http调用指定了期望的JSON,则无需在
相关文章:
- 如何解决取消抖动的用户输入上的竞争条件
- JavaScript 中的竞争条件
- Chrome扩展 chrome.storage 如何同时进行大量获取和设置并避免竞争条件
- 修复在执行http获取请求angularJS时的竞争条件
- JavaScript img.oner更改源-竞争条件时出错
- 使用jQuery提交表单时的竞争条件
- Firefox启动的扩展,在顶级中导入时的竞争条件
- Javascript-在检查对象属性是否存在时避免异步竞争条件
- 使用独立的 AngularJS 控制器修复竞争条件
- jQuery 事件的竞争条件
- 可能的 JavaScript ajax 调用竞争条件
- JS AJAX 提前键入结果排序/竞争条件
- JavaScript 承诺和竞争条件
- 具有多个“数据”事件处理程序和竞争条件的 NodeJS 流
- 在Javascript中竞争条件可能吗?(例如:我想原子地获取和设置值)
- 如何使用getter和setter方法创建一个Angular工厂而不遇到竞争条件
- 如何使用javascript使异步ajax半同步以避免竞争条件
- Koa.js在竞争条件下产生值
- 用于循环ajax潜在竞争条件的Javascript
- 可能的PHP/Javascript竞争条件