我有以下代码 -
this.storeNameValidate = function(stores) {
var deferred = $q.defer();
console.log(stores);
for (storeIndex in stores) {
this.nameValidate(stores[storeIndex].storeName, 3, 10)
.then(function() {
console.log("valid store name");
}, function() {
console.log("invalid store name");
deferred.reject("invalid store name");
})
}
return deferred.promise;
}
如果调用nameValidate错误块,我需要断开for循环。我怎样才能做到这一点 ?
我可以使用标记
来做到这一点this.storeNameValidate = function(stores) {
var deferred = $q.defer();
var flag = false;
console.log(stores);
for (storeIndex in stores) {
this.nameValidate(stores[storeIndex].storeName, 3, 10)
.then(function() {
console.log("valid store name");
var flag = true;
}, function() {
var flag = false;
console.log("invalid store name");
deferred.reject("invalid store name");
})
if (!flag)break;
}
return deferred.promise;
}
他们有更好的方法吗?
答案 0 :(得分:4)
您应该使用$q.all一组承诺并返回组合承诺。如果其中一个内部承诺失败,那么这个承诺就会拒绝。
this.storeNameValidate = function (stores) {
var promises = Object.keys(stores).map(function(storeIndex) {
return this.nameValidate(stores[storeIndex].storeName, 3, 10).then(function () {
console.log("valid store name");
}, function () {
return $q.reject("invalid store name");
});
}, this);
return $q.all(promises);
};
此外,不要滥用$q.defer
你不需要它。这种冗余使用称为deferred anti-pattern。
此外,如果您要拒绝的错误消息始终是"无效的商店名称" (不是特定于商店)并且您不需要在经过验证的商店上执行其他操作,您也可以一起省略错误和成功回调。然后代码将变得更加清洁:
this.storeNameValidate = function (stores) {
var promises = Object.keys(stores).map(function(storeIndex) {
return this.nameValidate(stores[storeIndex].storeName, 3, 10);
}, this);
return $q.all(promises);
};
答案 1 :(得分:1)
你误解了发生的事情。你的for循环在其他任何事情发生之前退出。它只是设置了所有的调用,然后它们都开始运行异步。你应该做的是保持(例如)一个名为“stop”的全局变量,并在调用validate错误时将其设置为“true”。那么在正常成功处理程序中,您可以检查stop是否为true,如果是,则不要执行任何其他操作。
真的,有正确的方法来处理它,你应该研究许多承诺的例子,你会看到他们如何做“拒绝”承诺,并做“当所有”,“什么时候”。您肯定希望通过非常简单的示例清楚地了解正在发生的事情,它将为您提供良好的服务。
答案 2 :(得分:0)
使用全局变量并在每次迭代时测试它,如果它设置为true
然后从循环中断:
var isCalled = false;
this.storeNameValidate = function(stores) {
var deferred = $q.defer();
console.log(stores);
for (storeIndex in stores) {
if(isCalled){break;} // break if the callback invoked
this.nameValidate(stores[storeIndex].storeName, 3, 10)
.then(function() {
console.log("valid store name");
isCalled = true;
}, function() {
console.log("invalid store name");
deferred.reject("invalid store name");
isCalled = true;
})
}
return deferred.promise;
}