Sync API 弃用
多年来,WebdriverIO 框架的一个卖点就是其同步 API。特别是对于来自 Java 或 Ruby 等更面向同步的语言的用户来说,它有助于在执行命令时避免竞争条件。但即使是更熟悉Promise的人也倾向于偏爱同步执行,因为它使代码更易于阅读和处理。
借助@wdio/sync
包,可以以同步方式运行异步命令。如果安装了该包,WebdriverIO 将自动使用利用fibers
包创建同步执行环境的实用程序方法包装命令。它使用一些内部 V8 API 来允许在单个线程中跨多个调用栈跳转。这种方法在其他项目中也很流行,例如Meteor,其中大部分代码都是使用异步 API 编写的,这导致开发人员必须不断以await
开头编写代码行。
去年,Fibers 包的作者宣布他将不再继续维护该项目。当 JavaScript 除了使用回调之外没有任何处理异步代码的适当机制时,他构建了 Fibers。随着 JavaScript 不断发展并添加了诸如Promise或Generator之类的 API,从技术上讲,除了代码风格偏好之外,Fibers 不再存在任何理由。现在,随着 Node.js v16 的发布以及对V8 v9 的更新,由于V8 中的更改,Fibers 停止工作,该更改将删除 Fibers 使用的一些内部接口。鉴于修复此问题并非易事,并且维护人员已退出该项目,因此我们不太可能在 Node.js v16 及更高版本中看到对 Fibers 的支持。
WebdriverIO 团队发现此问题后,立即采取措施并评估了我们的选择。我们发布了一个RFC,与社区讨论项目应朝哪个方向发展。我要感谢所有参与并提供意见的人。我们尝试了一些替代方案,例如使用 Babel 将同步代码转换为异步代码,但由于各种原因,它们都失败了。最终的决定是接受同步命令执行将不再可能的事实,而是拥抱异步性。
随着 WebdriverIO v7.9
的发布,我们很高兴地宣布我们改进了异步 API 并使其与同步 API 匹配。在链接元素命令调用时,用户之前必须编写如下所示的糟糕代码
await (await (await $('#foo')).$$('.bar'))[42].click()
现在这简化为以下内容
await $('#foo').$$('.bar')[42].click()
由于Proxy 对象的强大功能,API 现在更加简洁流畅,并且冗长性降低。这也有助于用户迁移使用同步 API 的项目以变得异步。该团队将致力于开发一个codemod,以帮助使此过程尽可能自动化和简化。
在此,WebdriverIO 团队想要感谢 Marcel Laverdet(GitHub 上的@laverdet
)多年来构建并维护 Fibers。现在是时候继续前进,并拥抱许多人辛勤工作的众多优秀 JavaScript 语言特性了。虽然我们已更新了文档中的代码示例,但@wdio/sync
将继续得到支持,直到我们停止支持 Node.js v14 及更早版本,这在 2023 年 4 月之前不会发生。您将有足够的时间使用async/await
慢慢迁移您的测试。
如果您对此有任何疑问或关于从使用同步命令编写框架到异步代码的迁移,请随时在我们的讨论论坛或我们的社区Discord支持服务器上给我们留言。