async和sync - angular的承诺问题
Promises issue with async and sync - angular
在一个移动cordova/angular项目中工作。下面是一个简单的服务调用:
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
是异步的,所以当它返回时,for
循环的k
远远不正确。
我考虑将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;
};
但是第二个参数被忽略并且总是未定义的。
如何克服这一点?
听起来你好像遇到了一个叫做"closure over the loop variable"的问题,这里详细讨论了这个问题:
JavaScript闭包内循环-简单的实际例子
但是,在您的情况下,干净的解决方案是将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指出的,避免延迟反模式:
this.getSomeData = function (id) {
var query = "SELECT * FROM Stuff";
return $cordovaSQLite.execute(db, query).then(function (res) {
return res.rows;
});
};
我就是这样让它工作的。我试着使用@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;
};
相关文章:
- 简单的ES6承诺问题-交换解决和拒绝参数
- 一个承诺换多个承诺-并发问题
- Node JS异步承诺.所有问题
- 在我的案例中,如何解决我的承诺问题
- 递归承诺调用 - 内存范围变量问题
- 循环中的承诺问题
- jQuery在一系列承诺上出现问题
- 在承诺函数从 pouchdb 填充数据之前触发 Ionic/Angular $watch的问题
- 有问题与承诺角度.控制台日志不适用于 HTTP 请求
- 了解使用AngularJS承诺,他们将如何帮助解决这个问题
- jquery承诺和骨干的问题
- 在 angularjs 控制器中对承诺调用进行单元测试时遇到问题
- Keystone.js嵌套承诺 -> foreach -> 列表查找范围问题
- JQuery承诺面临的问题
- 承诺,然后绑定问题
- 解析云代码-承诺问题
- 特定于Node-webkit的javascript回调/承诺问题
- 使用Everyauth的github身份验证的承诺问题
- async和sync - angular的承诺问题
- 使用Chai as promises解决了Protractor和Cucumber中的承诺问题