跳至主要內容

同步 API 棄用

·4 分鐘閱讀

多年來,WebdriverIO 框架的賣點之一是其同步 API。特別是對於來自 Java 或 Ruby 等更面向同步語言的人們來說,它有助於在執行命令時避免競爭條件。但對於更熟悉Promise的人們來說,也傾向於偏好同步執行,因為這使得程式碼更易於閱讀和處理。

在同步方式中執行非同步命令可透過@wdio/sync套件來實現。如果安裝了此套件,WebdriverIO 會自動使用實用方法封裝命令,這些方法使用fibers套件來建立同步執行環境。它使用一些內部 V8 API 來允許從單一執行緒內在多個呼叫堆疊之間跳轉。這種方法在其他專案中也很受歡迎,例如Meteor,其中大多數程式碼都是使用非同步 API 撰寫的,這導致開發人員不斷地在程式碼行開頭使用 await

去年,Fibers 套件的作者宣布他將不再繼續維護該專案。當 JavaScript 除了使用回呼之外沒有任何適當的機制來處理非同步程式碼時,他建立了 Fibers。隨著 JavaScript 的發展並增加了類似 PromiseGenerator 等 API,從技術上講,除了程式碼風格的偏好之外,沒有任何理由再讓 Fibers 存在。現在,隨著 Node.js v16 的發布以及更新到 V8 v9,由於 V8 的變更,將刪除 Fibers 使用的一些內部介面,導致 Fibers 停止運作。鑑於這個問題的修復不是微不足道的,而且維護者已經退出該專案,我們不太可能看到 Fibers 在 Node.js v16 及更高版本中的支援。

在 WebdriverIO 團隊發現這一點後,我們立即採取行動並評估了我們的選項。我們開啟了一個RFC,與社群討論專案應朝哪個方向發展。我想感謝所有提出意見並提供他們觀點的人。我們嘗試了一些替代選項,例如使用 Babel 將同步程式碼轉譯為非同步程式碼,但由於各種原因,它們都失敗了。最終決定是接受同步命令執行將無法繼續的可能性,並擁抱非同步性。

隨著 WebdriverIO v7.9 的發布,我們很高興地宣布,我們改進了我們的非同步 API,使其與同步 API 相符。當鏈接元素命令呼叫時,使用者以前必須編寫如下糟糕的程式碼

await (await (await $('#foo')).$$('.bar'))[42].click()

現在,它已簡化為如下所示

await $('#foo').$$('.bar')[42].click()

感謝 Proxy Object 的強大功能,API 現在更加精簡且不那麼冗長。這也將有助於使用者遷移使用同步 API 的專案以變為非同步。團隊將開發一個 codemod,以幫助盡可能自動化並簡化此流程。

在此時,WebdriverIO 團隊要感謝 Marcel Laverdet (GitHub 上的 @laverdet) 建立 Fibers 並維護這麼多年。現在是時候繼續前進,並擁抱許多人努力開發的所有優秀 JavaScript 語言功能。雖然我們已更新文件中的程式碼範例,但 @wdio/sync 將繼續受到支援,直到我們停止支援 Node.js v14 及更早版本,這不會在 2023 年 4 月之前發生。您將有足夠的時間使用 async/await 慢慢遷移您的測試。

如果您對此或從使用同步命令的框架遷移到非同步程式碼有任何疑問,請隨時在我們的討論區或我們的社群 Discord 支援伺服器中提出。

歡迎!我能幫您什麼嗎?

WebdriverIO AI Copilot