簡體   English   中英

使用Promise內部循環

[英]Using Promise inside loop

我想了解這段代碼是如何工作的。 有一段時間我一直在努力,但我想知道這里發生了什么。

for(let i=0 ; i< 3 ;i++){
   new Promise((resolve,reject)=>{
   console.log("i = "+i)
   resolve(i)
  })
  .then(r=>{
   console.log("promise 1  of "+r)
   return new Promise((res,rej)=>res(r))
  })
  .then(r=>{
    console.log("promise 2  of "+r)
    return new Promise((res,rej)=>res(r))
  })
}

console.log("finish")

輸出是

i = 0 
i = 1 
i = 2 
finish 
promise 1  of 0 
promise 1  of 1 
promise 1  of 2 
promise 2  of 0 
promise 2  of 1 
promise 2  of 2

為什么在其他承諾執行之前顯示完成。

提前致謝

為什么在其他承諾執行之前顯示完成。

因為該代碼中沒有任何內容告訴console.log在運行之前等待promises完成。 如果你想這樣做,將它們收集到一個數組中,然后使用:

Promise.all(theArray)
    .then(() => {
        console.log("finish");
    });

......告訴它等待他們。

請記住, then處理器是始終異步調用。 所以,你的代碼創建三支諾鏈,然后輸出console.log底,然后獲取異步回調到then處理程序-這樣的結果表明了之后。


旁注:問題中的代碼可以更簡單地寫成:

for(let i = 0; i < 3; i++) {
    console.log("i = " + i);
    Promise.resolve(i)
    .then(r => {
        console.log("promise 1  of " + r);
        return r;
    })
    .then(r => {
        console.log("promise 2  of " + r);
        return r;
    });
}

console.log("finish");

為什么:

  • promise的執行函數 (傳遞構造函數的函數)是同步運行的,所以使用console.log("i = " + i);之間沒有區別console.log("i = " + i); line作為執行函數的第一行,或者在您創建promise的行的上方。
  • Promise.resolve使用您提供的值創建已解決的承諾。
  • then 總是創造一個新的承諾。 當您從then處理程序返回一個非promise值時,該值是promise的解析值then返回。 如果你返回一個承諾,那么then創建的承諾是“奴役的”,以便你返回(等待它解決或拒絕,然后做同樣的事情)。

在評論中你提出了一個非常明智的問題:

如果“then”被異步調用那么這些承諾的輸出順序可能無法預測得對嗎?

小點: then不是異步調用,它的處理程序 (你傳遞它的函數)是異步調用的。

在一般情況下,是的,這是正確的,你無法預測獨立承諾的順序(那些沒有鏈接在一起的承諾)。 可以預測, 鏈接在一起的承諾(在鏈早期的前后來的處理)。 在你的代碼中,你有三個獨立的鏈(一個用於i = 0,一個用於i = 1,另一個用於i = 2); 每個鏈都有兩個處理器(“1”和“2”)。 所以你知道鏈“i = 0”中的“1”將在同一鏈中的“2”之前發生,但在一般情況下你不知道i = 0是第一個還是i = 2一個或其他什么。

但是 ,在這種特定情況下, 可以預測順序(至少在瀏覽器中,也可以在Node.js上),因為每個鏈中的初始承諾開始預先解析,這意味着對其then處理程序的調用放在microtaskqueue¹立即當你打電話then 微任務隊列在每個任務結束時運行(也稱為“macrotask”)。 因此,運行主代碼的任務會立即按順序將回調排隊到每個鏈的“1”處理程序。 當運行該處理程序時,它會將微任務排隊以調用“2 of”處理程序。 所以,由於承諾開始解決,我們知道我們會得到你得到的輸出。 但在一般情況下,你是正確的,你無法預測鏈之間

¹ 這是它的網絡術語; JS規范將其稱為PromiseJobs隊列。 更多關於這個答案中的 “微任務”和任務/宏任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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