背景
一般情况下,在RN中,调用原生方法是异步的,有没有办法同步的调用原生方法呢?其实是有的,RN早在2017年的一次commit 中就增加了此功能,只是直到去年底的一次发布中才被写在RN的文档中。目前樊登读书app应该还没有提供过同步的原生方法,但是 Community 中的一些库早就在使用了,比如 react-native-device-info 。
如何封装同步原生方法
如何封装同步的原生方法呢?文档中有介绍( Android / iOS),这里贴一个我封装的一个简单的例子(红框部分):
image
图中红框部分,@ReactMethod 注解中的 isBlockingSynchronousMethod = true 标记这是一个同步的(暴露到JS的)方法,返回String类型的值。
JS端使用:
const path = NativeModules.WXMultipleImageShare.getShareImagePath()
JS端直接调用此方法就能得到返回的String类型的值了。
iOS端的同步原生方法与此类似(使用RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD
这个宏定义),这里不再赘述。
注意
绝大部分场景下,使用异步原生方法是可以满足需求的。文档也建议一般情况下不要使用同步的方法,因为当前的旧架构(Birdge模式)下,同步方法可能会造成性能问题,还有可能引起多线程相关的bug。(其实简单情况下使用是没有任何问题的)。
(ps:如果有需要同步调用原生方法的场景,可以提出来一起讨论讨论)
同步方法在开启chrome调试时调用会报错,因为同步的方法需要app和js虚拟机共享内存,而当你使用chrome 调试时,rn的js代码是在chrome的v8 引擎中执行的(而不是app中的引擎或者手机系统引擎),然后通过WebSockets 与手机异步的通信。