簡體   English   中英

在for循環中中斷promise塊

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM