[英]Break out of promise block in a for loop
我有以下代碼 -
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;
}
他們有更好的方法嗎?
你應該使用$ q.all與promises數組並返回組合promise。 如果其中一個內部承諾失敗,這個承諾將拒絕。
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
,在你的情況下你不需要它。 這種冗余使用被稱為延遲反模式 。
此外,如果您要拒絕的錯誤消息始終是“無效的商店名稱”(不是特定於商店),並且您實際上不需要在經過驗證的商店上執行其他操作,您也可以同時省略錯誤和成功回調。 然后代碼將變得更加清潔:
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);
};
你誤解了發生的事情。 你的for循環在其他任何事情發生之前退出。 它只是設置了所有的調用,然后它們都開始運行異步。 你應該做的是保持(例如)一個名為“stop”的全局變量,並在調用validate錯誤時將其設置為“true”。 那么在正常成功處理程序中,您可以檢查stop是否為true,如果是,則不要執行任何其他操作。
真的,有正確的方法來處理它,你應該研究許多承諾的例子,你會看到他們如何做“拒絕”承諾,並做“當所有”,“什么時候”。 您肯定希望通過非常簡單的示例清楚地了解正在發生的事情,它將為您提供良好的服務。
使用全局變量並在每次迭代時測試它,如果設置為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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.