nebulasio / WebExtensionWallet

170 stars 58 forks source link

Feature request: 提供一个接口,用于返回钱包扩展当前的环境信息 #38

Open cssmagic opened 6 years ago

cssmagic commented 6 years ago

钱包扩展增加了 NasExtWallet 这个全局命名空间,这个势头非常好。期待它暴露更多的实用功能出来 👍

我提个需求:提供一个接口,用于返回钱包扩展当前的环境信息(主网 / 测试网 / 本地)。

另外,希望 NasExtWallet 提供的接口能做成同步的。现在的 .getUserAddress() 是异步的,但似乎是可以做成同步的?比如当钱包状态发生变化时主动注入(或发消息)到页面中?

因此,如果提供一个 NasExtWallet.getEnv() 接口,希望它是同步的。

yupnano commented 6 years ago

这里应该没办法做成同步的,web页面不能直接调用插件里的函数,只能通过发送消息来通信。用回调函数来处理也不麻烦。

getEnv() 可以增加,应该叫 getNetwork()

cssmagic commented 6 years ago

谢谢回复 ❤️

关于同步和异步的问题,我稍后整理一下思路。

cssmagic commented 6 years ago

如何实现 “同步获取扩展的某个状态”?

前提

首先需要确认,Chrome 扩展是否可以向所有 tab 发送消息?——我的所有思路基于这个前提条件。

我没写过 Chrome 扩展,只能简单搜索一下,发现至少 background.js 是可以做到这一点的。由此估计 popup.js 应该可也可以实现,或者说消息传输的通道应该是畅通的。心安了一些。

约定

为方便表述,把整个实现过程中的几方概括如下:

基本思路

由于 ExtPage 之间只能通过 postMessage() 进行通信,这个机制天然是异步的,如果要实现同步效果,需要变通。

Ext 可以向页面注入脚本 CS,此时 CS 就作为 ExtPage 中的接应。Ext 可以通过 postMessage()CS 进行通信:

CS 在接到 Ext 的通知之后保存状态。而当 Page 需要获取 Ext 的某个状态时,直接向 CS 查询就可以了——“同步获取” 的效果就实现了。

论证

为什么我们可以放心地把这个异步过程当作是同步的?最主要的原因还是用户本身是 “单线程的”。修改 Ext 中的状态、触发 Page 中的某向功能,都需要用户来操作,用户的操作是有间隙的,这个间隙对消息的传递和状态的传输来说,是完全足够的。

Page 中的脚本如果以极快的频率、自动连续、不间断地查询 Ext 的状态,是不是就穿帮了?理论上 Page 确实有可能会得到一次 “错误” 的结果,但由于这个脚本是自动且高速循环的,这个可能出现的错误实际上转瞬即逝,根本看不到。而且,更重要的是,想像不出这样做的实际意义是什么。

总结

与现有机制的差异:

一个 API 是同步还是异步,其实非常重要。同步 API 的理解成本和使用成本要低得多,希望能够实现,感谢!

cssmagic commented 6 years ago

同步和异步 API 如何并存?

最简单的方案是新增一个同步 API,老 API 不动。但为此增加一个新 API,似乎不划算。

所以理想方案还是让同一个 API 提供两种调用模式。

现有接口是异步的,机制修改之后,如何兼容同步与异步?

同一个接口可以同时支持同步和异步调用,印象中有些 API 是这样做的:

// 异步方式
getData(function (result) {
    /* 这里拿到 result 并处理 */
})

// 同步方式
var result = getData()
/* 这里拿到 result 并处理 */

或者换一种表达方式:

// 我有一个处理数据的函数
function handleData(result) {
    /* ... */
}

// 异步方式
getData(handleData)

// 同步方式
var result = getData()
handleData(result)

在实现上,统一使用新的同步机制。在异步模式下,让传入的回调函数异步执行(setTimeout)就可以了。

yupnano commented 6 years ago

非常感谢您的宝贵建议,后续版本更新中应该会参考。