2017-06-29 117 views
0

在我的角度應用程序中,我使用承諾在我的服務中調用方法,但由於我需要多次調用它,因此我在for循環中調用它。多次呼叫承諾

for(let item of this.arrayName) 
{ 
    this.service.funcName(item.name).then(result => {     
     //handle result     
    }).catch(err => {     
     //handle error 
    }); 
} 

但是當從多個調用同時獲得結果時會發生什麼?承諾知道如何處理它?它是否分別處理每個結果? 還是我需要鎖定代碼? 在此先感謝。

+0

你不能「呼籲承諾」。您可以調用返回承諾的函數。每個調用將(可能)返回一個單獨的承諾。 – 2017-06-29 12:30:40

回答

0

是的,承諾「知道」如何處理它。這是JavaScript的本質。 JavaScript事件循環在單個線程上運行,當IO操作(ajax,indexeddb,filesystem等)結束時,回調會附加到消息隊列中,並由事件循環持續消耗。這樣你就不必擔心任何競爭條件。此外,ECMAScript規範經過精心設計,可以隱藏每個可能出現爭用情況的地方。

這就是爲什麼您必須避免編寫阻止代碼的原因。如果你的代碼被阻塞,整個EventLoop被阻塞。現在,使用JavaScript創建這樣的攔截代碼非常困難,但仍然不是不可能的。

Concurrency model and Event Loop on MDN

0

你在做什麼是創建於this.arrayName每個項目的一個承諾。

這應該很好,只要每個項目的每個處理是完全獨立的。但是你必須要小心的是,在promise被解決並且隨後被處理之前,你的代碼執行將繼續超出for循環。所以你可能想繼續等待所有的承諾完全解決。

你可以在東西做到這一點像下面這樣:

Promise.all(this.arrayName.map(name => { 
    return this.service.funcName(name).then(result => {     
     //handle result     
    }).catch(err => {     
     //handle error 
    }); 
}) 
.then(...) // all success - do success case 
.catch(...) // some failed - handle error case 
0

什麼Samir said是正確的。每次調用該函數時,都會調用返回語句return new Promise(...)(這是使用promise的預期方式)。

JavaScript也具有閉包的概念,閉包意味着傳遞給該函數的參數僅在該函數的執行中出現。所有原始數據(包括對象引用被「關閉了」,因此當循環改變item,它不會影響之前的函數調用。

唯一的問題還是要問的是你是否真的要並行他們都執行。你所擁有的循環將執行所有這些,而不必等待先前的解決方案。

由於您使用的是Angular,請查看Observables。他們的學習曲線有些陡峭(您在使用時會有不同的想法),但他們是非常有用的,一旦你瞭解他們。

引言,幫助我fi最終了解Observables是這樣的:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754