使用移动cordova /角项目。以下是一个简单的服务电话:
this.getSomeData = function (businessId) {
var deferred = $q.defer();
var query = "SELECT * FROM Stuff";
$cordovaSQLite.execute(db, query).then(function (res) {
deferred.resolve(res.rows);
}, function (err) {
deferred.reject(err);
});
return deferred.promise;
};
问题很简单:
for (var k = 0; k < count; k++) {
myService.getSomeData($scope.model.stuff[k].id, k).then(function (data) {
// whatever
}
);
getSomeData
是异步的,所以当它返回时,k
周期的for
远非正确。
我想过将k
作为参数传递给服务方法:
for (var k = 0; k < count; k++) {
myService.getSomeData($scope.model.stuff[k].id, k).then(function (data) {
// whatever
}
);
并相应地更改服务方法:
this.getSomeData = function (id, index) {
var deferred = $q.defer();
var query = "SELECT * FROM Stuff";
$cordovaSQLite.execute(db, query).then(function (res) {
deferred.resolve(res.rows, index);
}, function (err) {
deferred.reject(err);
});
return deferred.promise;
};
但是第二个参数被忽略,并且总是未定义。
如何克服这个问题?
答案 0 :(得分:0)
听起来你遇到了一个叫做“关闭循环变量”的问题,这个问题在这里有详细讨论:
JavaScript closure inside loops – simple practical example
但是,在您的情况下,干净的解决方案是将Array#map
与$q.all()
合并:
$q.all($scope.model.visits.map(function (stuff) {
return myService.getSomeData(stuff.id);
})).then(function (results) {
// results is an array of the results of all the calls to getSomeData() in the correct order
});
另外,正如Bergi指出的那样,避免使用deferred antipattern:
this.getSomeData = function (id) {
var query = "SELECT * FROM Stuff";
return $cordovaSQLite.execute(db, query).then(function (res) {
return res.rows;
});
};
答案 1 :(得分:0)
这就是我的工作方式。我尝试使用@ JLRishe的建议,但它不起作用。事实证明,我设法将多个参数传递给服务方法并返回到控制器(通过构建一个对象而不是包含我需要的多个参数)。
myService.getSomeData().then(
function (stuff) {
// whatever
}
).then(function () {
for (var i = 0; i < $scope.model.stuff.length; i++) {
// HERE I SEND TWO PARAMETERS TO THE SERVICE METHOD
myService.getSomeMoreData($scope.model.stuff[i].id, i).then(
function (data) {
// whatever
}
);
}
});
this.getSomeMoreData = function (id, index) {
var deferred = $q.defer();
var query = "SELECT * FROM stuff";
$cordovaSQLite.execute(db, query).then(function (res) {
var moreStuff = [];
for (var i = 0; i < res.rows.length; i++) {
var junk = res.rows.item(i);
moreStuff.push(junk);
}
// HERE I RESOLVE AN OBJECT INSTEAD OF TWO PARAMETERS
deferred.resolve({
moreStuff: moreStuff,
index: index
});
}, function (err) {
deferred.reject(err);
});
return deferred.promise;
};