2017-04-07 101 views
0

我嘗試在迭代某些對象屬性時拒絕承諾,但即使在調用了拒絕方法後仍繼續執行(在此控制檯中記錄了「通過此處!!!」即使在拒絕之後)。在遍歷對象屬性時解析或拒絕承諾

function updateDocumentWithNewData(document, newData) { 
 
return new Promise(function(resolve, reject) { 
 
    //some code... 
 
    for (let key in newData) { 
 
     if (newData.hasOwnProperty(key)) { 
 
     //verifying if the document already has the property 
 
     if (document.hasOwnProperty(key)) { 
 
      reject({'message' : 'a property already exists...'}); 
 
     } 
 
     //some code... 
 
     } 
 
    } 
 
     
 
    //some more code... 
 
    console.log("passed here!!!"); 
 
    resolve(document); 
 
    }); 
 
}

我打電話返回這個承諾是這樣的方法:

updateDocumentWithNewData(doc, data).then(function(result) { 
 
    //Some code 
 
}).catch(function(err) { 
 
    //Some code 
 
});

的解決方案是使用一個布爾變量,和呼叫僅在循環結束之後「拒絕」方法:

function updateDocumentWithNewData(document, newData) { 
 
    return new Promise(function(resolve, reject) { 
 
    //some code... 
 
    let invalidUpdate = false; 
 
    for (let key in newData) { 
 
     if (newData.hasOwnProperty(key)) { 
 
     //verifying if the document already has the property 
 
     if (document.hasOwnProperty(key)) { 
 
      invalidUpdate = true; 
 
      break; 
 
     } 
 
     //some code... 
 
     } 
 
    } 
 
    if (invalidUpdate) { 
 
     reject({'message' : 'a property already exists...'}); 
 
    } 
 
    
 
    //some more code... 
 
    console.log("passed here!!!"); 
 
    resolve(document); 
 
    }); 
 
}

我不知道如果我錯過了一些愚蠢的事,但我認爲,拒絕承諾的應imediatelly返回時「拒絕」之稱,並打破剩下的代碼執行,所以第一個代碼應該可以工作。有什麼我失蹤了嗎?

回答

2

調用reject不會阻止承諾執行,它只會將承諾狀態設置爲rejected。它不會使承諾中斷代碼執行。 (但是,你不會有調用resolve後來的任何問題,作爲一個無極的狀態只能從pending更改爲rejectedfulfilled正好一次)

如果你想打破代碼執行,你需要使用return reject(reason)(或者return resolve(value))。否則,承諾將運行到其代碼結束,並且然後任何與承諾相關的.then回調將被調用。這是預期的行爲。立即停止承諾執行的另一種方式是拋出錯誤,這將導致承諾拒絕該錯誤。

因此,爲了使您的原代碼的工作方式是:

function updateDocumentWithNewData(document, newData) { 
return new Promise(function(resolve, reject) { 
    //some code... 
    for (let key in newData) { 
     if (newData.hasOwnProperty(key)) { 
     //verifying if the document already has the property 
     if (document.hasOwnProperty(key)) { 
      return reject({'message' : 'a property already exists...'}); 
     } 
     //some code... 
     } 
    } 

    //some more code... 
    console.log("passed here!!!"); 
    resolve(document); 
    }); 
} 
+0

謝謝,佩德羅。完美的解釋 - 現在我在用Promise測試中看到的其他一些奇怪的行爲也很有意義! :) –