Chrome扩展程序API是否支持Promise?

20
在过去的几周中,我一直在编写一些浏览器扩展程序,一直以为Firefox的WebExtension在Chrome中也可以自动运行。所以我试着按照Mozilla的示例编写代码。
但是今天我意识到,在Chrome扩展API文档中没有提到Promises。
我已经在整个代码中严格使用了Promises来开发所有的Extensions。

现在我的问题是,我的代码能在Chrome上工作吗?或者如果我在最顶部添加一个var browser = chrome声明,它会起作用吗?
或者Chrome根本不支持API上的Promises?
如果Chrome还不支持API函数中的Promises,未来会支持吗?

请注意,我知道这个项目:https://github.com/mozilla/webextension-polyfill
但我不想在每个地方都包含它,因为它有讨厌的bug。

除此之外,由于隐私和安全原因,我没有Chrome或Chromium并且无法安装它们。

编辑:他们终于开始实现 Promises 的支持了。


1
是的,正如您在polyfill描述中所看到的,它在Chrome中是必需的。至于未来,工作尚未开始。不过在https://crbug.com上有一个问题。 - wOxxOm
4
https://crbug.com/328932 - Daniel Herr
我不明白为什么Mozilla的WebExtensions API兼容性表中列出了Chrome对browser.alarm之类的功能提供完全支持,而实际上Chrome并没有browser对象。 - askvictor
我想Chrome通过chrome.alarm支持它。只是没有Promise支持。 - Forivin
5个回答

9
直到今天,我认为Firefox的WebExtension在Chrome中应该可以自动工作。 WebExtensions是为了与Chrome扩展程序向后兼容而创建的。 支持的API可用于chrome.*命名空间。目标是简化将现有扩展移植到FF以快速启动生态系统。然而,Mozilla忽略了与browser.*命名空间的前向兼容性。 Mozilla决定采用基于Promise的方法来处理API,但仅适用于该新命名空间。所以现在我的问题是,我的代码能在Chrome中工作吗?或者如果我在顶部添加var browser = chrome声明会起作用吗?不行,它们的行为不同,签名也不同。 Chrome将拒绝没有必需的显式回调的调用。 browser.*变体将发出Promise。或者Chrome根本不支持API上的Promises?如果Chrome尚未支持API函数上的Promises,那么它将在未来支持它们吗?
如评论中所述,基于Promise的API重写被Chrome考虑, 并且已经被实现或开始实现用于MV3扩展。但是,还存在包括您提到的那个在内的polyfills。除了自己包装方法以创建自己的polyfill之外,没有其他解决方案。

此外,我没有Chrome或Chromium,也不能出于隐私和安全原因安装它们。

那么您无法正确测试您的端口; 对于您的潜在用户来说,这不是一个好方法。在这种情况下,最好不要进行端口转换。


2
有一个 polyfill 可以让使用 Firefox APIs 的扩展在 Chrome 上运行: https://github.com/mozilla/webextension-polyfill - phiresky

9
官方承诺的支持终于来了,并且已经在一些API上实现。撰写本文时:

在GoogleChrome的Github上,您可以找到一个使用chrome.tabs API和Promises (await)的Hello world示例:

chrome.runtime.onInstalled.addListener(async () => {
  let url = chrome.runtime.getURL("hello.html");
  let tab = await chrome.tabs.create({ url });
  console.log(`Created tab ${tab.id}`);
});

从上面你可以看到,promise支持已在chrome对象中实现,它现在同时支持Promise和回调函数。而Firefox仍然使用browser对象作为promise API。


2
await chrome.storage.local.get() does not seem to work though, it returns undefined - Atul Yadav
我可以确认这一点。但我不知道为什么会发生这种情况。我猜可能是因为并非所有这些更改都已经被纳入最新的稳定版本中了。 - Forivin
是的,非常奇怪。只是为了将 chrome.storage API 转换成 Promise 需要维护额外的代码 ☹️ - Atul Yadav

4
我还没有查看过浏览器API,所以我可能会跑偏,但如果唯一的区别是Firefox API返回promise而不是使用回调函数,那么chrome-promise库或许能够帮助您。它将需要回调函数的所有API调用封装在返回promise的函数中。
然后您可以在Chrome中执行类似这样的操作:
var browser = new ChromePromise(); 

然后进行promise调用:

browser.storage.local.get(null).then(data => console.log(data));

如果您将browser变量定义为全局变量,并在任何其他脚本之前包含该脚本,则可以将其用作全局变量,而不必在要使用它的每个文件中都包含polyfill。
编辑:chrome-promise的作者除修复漏洞外已不再维护它。他们在这里列出了一些替代库,其中包括OP拒绝的Mozilla webextension-polyfill。该库的自述文件说明了如何在需要的各种扩展上下文中将其作为全局变量可用

1
我创建了这个库https://github.com/lawlietmester/webextension,与webextension-polyfill不同的是,它没有一个通用规则。
我的库是一种跨浏览器的方法,可以创建一个Browser对象,而不需要修改原始的chrome/browser。就像旧时的jQuery一样。
只需在后台进程中导入它并使其成为后台全局变量,然后对于其他导入(例如从弹出窗口),请使用以下导入: ( typeof browser === 'undefined' ? chrome : browser ).extension.getBackgroundPage().Browser

0

我在Spellbook上的方法是将必要的方法转换为返回promises并在包装的回调函数上检查chrome.runtime.lastError。

但现在我只需遍历所有适当的chrome API方法,并使用上述方法将它们转换为基于promise的方法。

这里是Spellbook上相关提交的链接

我计划将其提取到一个名为Rosegarden的小型库中,因为Mozilla的webextension-polyfill似乎太复杂了...


这是我承诺的1.7kb库,名为Rosegarden: - peterhil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接