Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
cssmagic opened this issue Jul 25, 2018 · 5 comments

Comments

@cssmagic
Copy link

cssmagic commented Jul 25, 2018

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

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

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

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

@yupnano
Copy link
Contributor

yupnano commented Jul 25, 2018

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

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

@cssmagic
Copy link
Author

谢谢回复 ❤️

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

@cssmagic
Copy link
Author

cssmagic commented Aug 6, 2018

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

前提

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

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

约定

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

  • Page - 页面
  • Ext - 扩展
  • CS - 扩展注入到页面中的脚本(这里就不细分 contentscript 和 inpage 了)

基本思路

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

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

  • 每当 Chrome 新开一个页面,Ext 就需要向页面中的 CS 通报自己的当前状态(比如当前钱包地址、当前所处网络等)。
  • 当用户在 Ext 中发生某些变更状态的操作时(比如更换钱包地址、切换网络状态等),Ext 向所有页面中的 CS 发出通知。

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

论证

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

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

总结

与现有机制的差异:

  • 以前是 Page 在需要时向 Ext 查询,Ext 一直处于被动等待状态;现在 Ext 会把自己的状态变化主动广播出去。
  • 以前是 Ext 发消息,Page 中的 nebPay 来接;现在 Ext 既然已经向 Page 注入 CS 了,那不妨让 CS 来接 Ext 的消息。PageCS 查询,自然就是同步的了。

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

@cssmagic
Copy link
Author

cssmagic commented Aug 6, 2018

同步和异步 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
Copy link
Contributor

yupnano commented Sep 3, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants