我需要对Angular资源进行多个并发调用,并使用$ promise api链接一些操作。
我定义了像这样的资源
myServicesModule.factory('MyResource', ['$resource', 'SETTINGS', function($resource, SETTINGS) {
return $resource(SETTINGS.serverUrl + '/myResource/:id', { },
{
get: { method: "get", url: SETTINGS.serverUrl + '/myResource/show/:id' },
}
);
}]);
我的控制器需要检索多条记录,并在记录准备就绪时对每条记录执行操作。我无法将值传递给then()闭包。
当我这样做时:
for (var i = 0; i < 3; i++) {
MyResource.get({id: i}).$promise.then(function(item) { console.log(i); });
}
输出为&#34; 2,2,2&#34;。
此代码产生&#34; 0,1,2和#34;的所需输出。 (顺序取决于每个资源调用何时完成),但这是一个丑陋的解决方案。
for (var i = 0; i < 3; i++) {
var closure = function(i) {
return function(item) { console.log(i); console.log(item); }
}
UwgCarrier.get({id: i}).$promise.then( closure(i) );
}
为什么第一个代码段返回&#34; 2,2,2&#34; ?
有没有更清洁的方法来解决这个问题?
答案 0 :(得分:1)
这是关闭的问题。只需将你的封闭包裹在另一个封闭中
您可以通过调用立即函数来制定解决方法,如下所示:
for (var i = 0; i < 3; i++) {
(function(c) {
UwgCarrier.get({id: c}).$promise.then( console.log(c); );
})(i);
}
在我的例子中,我将“i”替换为“c”到闭包中以使事情变得清晰。像这样,立即函数在循环过程中使用其当前值调用“i”。
我不认为有更好的方法可以做到这一点,因为这是一个javascript问题。
编辑:
随着ES6即将推出,您可以使用“let”关键字来实现相同的目标,而无需将内部循环包含在闭包中,因为“let”会阻塞变量。
for (let i = 0; i < 3; i++) {
UwgCarrier.get({id: i}).$promise.then( console.log(i); );
}