首頁 > web前端 > js教程 > 主體

為什麼 Promise 執行順序與 JavaScript 中的期望不符?

Patricia Arquette
發布: 2024-10-25 08:01:28
原創
397 人瀏覽過

Why Doesn't the Order of Promise Execution Match Expectations in JavaScript?

JavaScript Promise 中的執行順序是什麼?

問題:

以下程式碼片段示範了 JavaScript 的使用Promise,而且執行順序很耐人尋味。

<code class="javascript">Promise.resolve('A')
  .then(function(a){console.log(2, a); return 'B';})
  .then(function(a){
     Promise.resolve('C')
       .then(function(a){console.log(7, a);})
       .then(function(a){console.log(8, a);});
     console.log(3, a);
     return a;})
  .then(function(a){
     Promise.resolve('D')
       .then(function(a){console.log(9, a);})
       .then(function(a){console.log(10, a);});
     console.log(4, a);})
  .then(function(a){
     console.log(5, a);});
console.log(1);
setTimeout(function(){console.log(6)},0);</code>
登入後複製

結果顯示執行順序是:

1
2 "A"
3 "B"
7 "C"
4 "B"
8 undefined
9 "D"
5 undefined
10 undefined
6
登入後複製

提出的問題是為什麼執行順序不是1, 2 , 3, 4...,1, 2, 3, 4 .... 的期望與結果有何不同?

答案:

註解:

在.then() 處理程序中執行Promise,而不是從.then () 回呼返回它們,會建立一個新的、獨立的Promise 序列,該序列不會與任何父Promise 同步。方式。這通常被認為是一個錯誤,一些承諾引擎在發生時會發出警告,因為它通常不是預期的行為。一個有效的用例可能是「即發即忘」操作,其中既不關心錯誤,也不關心同步。

.then() 處理程序中的 Promise.resolve() Promise 建立獨立於父級運作的新 Promise 鏈鏈。對於實際的非同步操作(例如 AJAX 呼叫),獨立的、斷開連接的 Promise 鏈沒有可預測的行為。完成時間是不確定的,就像並行啟動四個 AJAX 調用,但完成順序未知。在提供的程式碼中,所有操作都是同步的,從而產生一致的行為,但不應依賴這一點,因為 Promise 的設計目的是非同步執行。

總結:

  1. 所有 .then() 處理程序在目前執行緒完成後非同步呼叫。這種一致性包括同步解決的 Promise,例如 Promise.resolve().then(...),以防止計時錯誤。
  2. setTimeout() 與計劃的 .then() 處理程序沒有指定的順序。雖然所使用的實作將掛起的 .then() 處理程序放置在掛起的 setTimeout() 之前,但 Promises/A 規範允許在 setTimeout() 之前或之後進行調度。
  3. 獨立的 Promise 鏈沒有可預測的執行順序。
  4. 如果執行順序至關重要,請避免創建依賴於微小實作細節的競爭。相反,連結 Promise 鏈以強制執行特定順序。
  5. 避免在 .then() 處理程序中建立獨立的 Promise 鏈,除非是「即發即忘」場景。

逐行分析:

  1. 初始 Promise 鏈已啟動,並附加了 .then() 處理程序。由於 Promise.resolve() 立即解析,因此第一個 .then() 處理程序計劃在目前 JavaScript 執行緒完成後執行。後續 .then() 處理程序位於第一個處理程序之後的頂級鏈中,並且僅在第一個處理程序完成後執行。
  2. setTimeout() 在執行緒的末尾運行,並安排一個計時器。
  3. 同步執行完成後,事件佇列執行剩餘的任務。
  4. 第 1 行定義的 .then() 處理程序執行,並記錄 '2 "A"'。
  5. 呼叫後續的 .then() 處理程序,並建立一個新的獨立 Promise 鏈,其中的 .then() 處理程序計劃在目前執行緒完成時執行。此處理程序在子鏈的 .then() 處理程序運行之前列印 '3 "B"',後者列印 '7 "C"'。
  6. 然後呼叫第 12 行中定義的 .then() 處理程序,並且再次建立一個新的 Promise 鏈,調度一個 .then() 處理程序。從此處理程序記錄“4 "B"”。
  7. 子鏈中預定的 .then() 處理程序運行,列印「8 undefined」。
  8. .then() 處理程序隨後呼叫第 19 行中定義的內容,並建立另一個獨立的 Promise 鏈,調度 .then() 處理程序。從此處理程序列印 '5 undefined'。
  9. 最後,呼叫第 15 行定義的 .then() 處理程序,並列印 '10 undefined'。
  10. 執行setTimeout()

結論:

.then() 處理程序中的Promise.resolve() 承諾執行缺乏特定的順序,以及各種引擎的.then() 處理程序調度與setTimeout() 的不確定性,突顯了透過連結承諾控制執行順序的重要性。

以上是為什麼 Promise 執行順序與 JavaScript 中的期望不符?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!