我无法正确使用角度$q
和Javascript' promise
api。然后,我对Javascript很新,可能会出现语法错误。
This问题似乎相似,但它似乎并不是一个精确的副本...
我的服务有这样的方法(由我的控制器调用):
self.getResources = function() {
let promises = [];
for (let resourceName in $rootScope.resourceNameList) {
promises.push($http({
url : '/' + resourceName,
method : 'GET'
}).then(function (res) {
return { resourceName : res.data};
}));
}
return promises;
};
我的控制器将返回的承诺列表传递给有角度的$q.all()
:
let promises = resourceService.getResources();
$q.all(promises).then(function (resultsArray) {
// resultsArray should be an array of elements like:
// [ {cars : [...]}, {coffeePots : [...]}, {motorBoats : [...]} ]
// with size = resourceNameList.length(), correct?
// this log is never called.
console.log(resultsArray);
$scope.resources = resultsArray;
});
最后,在我的HTML中,我尝试迭代并显示资源:
.
.
.
<!-- 'cars' is and example, but I am trying to retrieve this data in the same way -->
<tr ng-repeat="item in resources[cars]">
<td>{{item.property1}}</td>
<td>{{item.property2}}</td>
</tr>
该表未显示任何结果。
我可以从控制台看到HTTP请求成功并返回数据,因此我必须使用promise
或$q
apis时出错。
有什么建议吗?
非常感谢。
答案 0 :(得分:2)
我知道这可能是一个非答案,因为你已经发现你的输入数据集确实存在错误,但是你应该通过添加.catch
来实际检测到这类问题(至少)你的根承诺,所以你可以立即看到实际上是什么。
在您的情况下,这是您的根承诺(已经附加了捕获)。 为了清晰起见,我把它分成了新行:
let promises = resourceService.getResources();
$q
.all(promises)
// unfortunately, .then only gets executed if all of these promises succeed.
.then(function (resultsArray) {
console.log(resultsArray);
$scope.resources = resultsArray;
})
// there is a disturbance in the force!
.catch(function (error) {
// you can console.log(error) OR
window.open("https://stackoverflow.com/search?q="+error.message);
})
;
编辑:如果您需要在$q.all
上过滤掉失败的承诺,只需将其替换为$q.allSettled
!完整API在此处:https://github.com/kriskowal/q
要分享的其他一些想法:很快,您会发现自己抱怨$q
缺少某些功能,例如将.push
或.map
与.all
结合使用等等。已经有了一个图书馆;你可以使用BluebirdJS!角度为here's a nifty wrapper for it。相反,你的代码看起来像这样:
Promise.map($rootScope.resourceNameList, function(resourceName) {
return $http({
url : '/' + resourceName,
method : 'GET'
});
}, {concurrency: 3}) // did I mention you could control concurrency?
.then(function(results) {
console.log(results); // $http promises that were resolved!
},function(rejects) {
console.log(rejects); // $http promises that were rejected :(
})
.catch(function (error) {
// you can console.log(error) OR
window.open("https://stackoverflow.com/search?q="+error.message);
})
;
好多了,对吧?
快乐的编码!以下是关于承诺的精彩内容:http://taoofcode.net/promise-anti-patterns/
答案 1 :(得分:0)
您需要在指令中注入$ q和$ http,如此
self.getResources = function($q,$http) {
let promises = [];
for (let resourceName in $rootScope.resourceNameList) {
promises.push($http({
url : '/' + resourceName,
method : 'GET'
}).then(function (res) {
return { resourceName : res.data};
}));
}
return promises;
};