当前位置: 首页 > news >正文

JavaScriptProxy 和 runJavaScript:ASCF 里两根最重要的桥


title: JavaScriptProxy 和 runJavaScript:ASCF 里两根最重要的桥
date: 2026-06-26
category: HarmonyOS
tags:

  • HarmonyOS
  • ArkWeb
  • JavaScriptProxy
  • runJavaScript
  • JSBridge
    description: 专门解释 H5 到 ArkTS、ArkTS 到 H5 两个方向的通信:JavaScriptProxy 和 runJavaScript 分别解决什么问题。

JavaScriptProxy 和 runJavaScript:ASCF 里两根最重要的桥

看 ASCF 这类架构,最先要搞清楚的不是 IPC,也不是 JSVM,而是这两个东西:

JavaScriptProxy runJavaScript

它们一个负责 H5 调 ArkTS,一个负责 ArkTS 回调 H5。

如果这两个方向没搞清楚,后面讲 Controller、Dispatcher、JSAPI、NAPI 都会乱。


一、先从一个按钮开始

H5 页面里有一个按钮:

<buttononclick="callNative()">调用 ArkTS</button>

点击之后,H5 希望把请求发给 ArkTS。

在 MyASCF 里,它会这样写:

window.ascfBridge.send(JSON.stringify({requestId:'req_001',action:'runtime.ping',params:{from:'h5'},timeout:5000}))

这里的window.ascfBridge不是浏览器原生对象。

它是 ArkTS 通过 ArkWeb 注入给 H5 的对象。

这就是JavaScriptProxy


二、JavaScriptProxy:H5 调 ArkTS

JavaScriptProxy解决的问题是:

前端页面里的 JavaScript,怎么调用应用侧 ArkTS 方法?

ArkTS 侧注册一个对象:

.javaScriptProxy({object:this.bridge,name:'ascfBridge',methodList:['send'],controller:this.webController})

H5 侧就可以调用:

window.ascfBridge.send(rawReq)

所以它的方向是:

H5 / JavaScript ↓ JavaScriptProxy ↓ ArkTS

这句话很重要:

JavaScriptProxy 是 H5 → ArkTS。

它不是 ArkTS 回调 H5。


三、AscfBridgeObject:桥对象只是入口

在 MyASCF 里,ascfBridge对应 ArkTS 侧的AscfBridgeObject

它大概做这件事:

H5 调 window.ascfBridge.send(rawReq) ↓ AscfBridgeObject.send(rawReq) ↓ BridgeController.handle(rawReq)

注意,AscfBridgeObject不应该承担太多业务。

它最好只做入口:

打印日志 接收 rawReq 交给 Controller

因为真正的协议解析、分发、业务处理,应该交给后面的层:

Controller Dispatcher Register Biz Imp

这样桥对象就不会越来越臃肿。


四、为什么 H5 不直接拿 send 的返回值?

一开始你可能会这样写:

constres=window.ascfBridge.send(rawReq)

这看起来很简单。

但是 ASCF 这种能力调用,更接近异步模型:

H5 发请求 ArkTS 处理 可能调用系统 API 可能调用 C++ 可能失败 可能超时 最后再回调 H5

所以更好的做法是 Promise:

window.ascf.send('runtime.ping',params).then(res=>{console.log('success',res)}).catch(err=>{console.log('failed',err)})

H5 发出去之后,不是马上拿返回值,而是等 ArkTS 处理完,再通过回调回来。

这时候就需要第二根桥:runJavaScript


五、runJavaScript:ArkTS 回调 H5

runJavaScript解决的问题是:

ArkTS 怎么主动调用 H5 页面里的 JavaScript 函数?

H5 先定义一个全局函数:

window.__ascfResolve=function(response){constitem=window.ascf.pendingMap.get(response.requestId)if(!item){console.log('pending request not found')return}window.ascf.pendingMap.delete(response.requestId)if(response.code===0){item.resolve(response)}else{item.reject(response)}}

ArkTS 处理完之后:

this.webController.runJavaScript(`window.__ascfResolve(${responseJson})`)

这时 H5 页面里的window.__ascfResolve被执行。

所以方向是:

ArkTS ↓ runJavaScript ↓ H5 / JavaScript

记住:

runJavaScript 是 ArkTS → H5。

六、pendingMap:Promise 怎么和回调对应起来?

H5 发请求时,会生成一个requestId

constrequestId='req_'+Date.now()

然后把 Promise 的resolvereject保存起来:

window.ascf.pendingMap.set(requestId,{resolve,reject})

请求发给 ArkTS:

window.ascfBridge.send(JSON.stringify(request))

ArkTS 处理完之后,回调 H5:

window.__ascfResolve({requestId:'req_001',code:0,message:'success',data:{}})

H5 再用requestId找到对应 Promise:

constitem=window.ascf.pendingMap.get(response.requestId)

所以requestId是异步回调的钥匙。

没有它,多个请求同时发出时,H5 就不知道哪个结果对应哪个请求。


七、两根桥合起来就是 JSBridge

现在可以把主链路写清楚了:

H5 ↓ window.ascf.send(...) ↓ window.ascfBridge.send(rawReq) ↓ JavaScriptProxy ↓ ArkTS Controller / Dispatcher / Biz / Imp ↓ runJavaScript ↓ window.__ascfResolve(response) ↓ H5 Promise resolve

这就是 MyASCF 的 JSBridge 模型。

注意,不要把这两个方向说反:

JavaScriptProxy:H5 → ArkTS runJavaScript:ArkTS → H5

八、JavaScriptProxy 和 runJavaScript 不是 IPC

这两个 API 是你在应用层能看到的接口。

但是如果 H5 页面运行在 WebView 渲染进程,ArkTS 逻辑运行在应用主进程,那么底层跨进程传消息时,框架内部可能会走 IPC。

所以层级关系应该是:

应用层能看到: JavaScriptProxy / runJavaScript 框架底层可能涉及: IPC / RenderProcess / Main Process

不能简单说:

JavaScriptProxy = IPC runJavaScript = IPC

更准确是:

JavaScriptProxy 和 runJavaScript 是上层桥接口; IPC 是底层跨进程通信机制。

九、在 MyASCF 里如何验证?

你可以在 H5 和 ArkTS 两边都打日志。

H5:

[H5] create request [H5] call window.ascfBridge.send [H5] window.__ascfResolve called [H5] Promise resolve

ArkTS:

[ASCF][Bridge] JavaScriptProxy send rawReq [ASCF][Controller] parsed request [ASCF][Dispatcher] dispatch action [ASCF][Register] get handler [ASCF][Controller] callbackToH5 [ASCF][WebRuntimePage] runJavaScript

看到这组日志,就说明两根桥跑通了。


十、总结

这篇只记住一句话:

JavaScriptProxy 解决 H5 调 ArkTS。 runJavaScript 解决 ArkTS 回调 H5。

它们合起来,让 H5 和 ArkTS 可以形成一次完整的异步调用。

但是,它们不是 IPC,也不是 JSVM,也不是 NAPI。

下一篇再讲这些运行时概念:

IPC、JSVM、UIThread、libuv 到底分别是什么?

参考资料

  • ArkWeb 前端页面调用应用侧函数:JavaScriptProxy / registerJavaScriptProxy
    https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/web-in-page-app-function-invoking
  • ArkWeb 应用侧调用前端页面函数:runJavaScript / runJavaScriptExt
    https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/web-in-app-frontend-page-function-invoking
  • WebviewController API 参考
    https://developer.huawei.com/consumer/en/doc/harmonyos-references/arkts-apis-webview-webviewcontroller
  • pasteboard 剪贴板 API
    https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-pasteboard
  • Node-API / NAPI
    https://developer.huawei.com/consumer/en/doc/harmonyos-references-V14/napi-V14
  • IPC / RPC 开发指导
    https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ipc-rpc-development-guideline
  • JSVM API 参考
    https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/_j_s_v_m-V5
http://www.gsyq.cn/news/1608511.html

相关文章:

  • OpenCore配置管理技术革命:OCAT图形化工具深度解析与实践指南
  • 告别官方IDE:在VS 2022中构建高效Arduino开发与调试工作流
  • 【FPGA实战】深入解析M25P16 SPI Flash的驱动设计与时序控制
  • 从DVD到8K HDR:聊聊BT601、BT709、BT2020标准背后的那些事儿
  • 从JSON到清晰时序:WaveDrom在数字设计中的高效波形绘制实战
  • 抖音内容自动化采集工具深度解析:架构设计与实战应用
  • 从原理到选型:5大主流LED调光技术深度解析
  • 构建企业级权限管理平台:ZR.Admin.NET跨平台RBAC解决方案实战指南
  • Web身份验证漏洞攻防实战:从暴力破解到MFA绕过的全面防御指南
  • 抖音直播录制神器:3步快速部署40+平台自动录制完整指南
  • TinyML 推理引擎:从模型量化到 MCU 级部署的极致内存优化
  • 你玩的游戏,可能正在帮外国军队扫描你的国家
  • 英雄联盟Akari助手:3分钟快速上手的游戏效率工具终极指南
  • WWW 2024 | 图嵌入新范式:从LINE到大规模动态网络的表示学习
  • 在Java中,如何使用break和continue关键字来控制循环?
  • STC16F40K128单片机驱动4路红外循迹模块实战指南
  • 使用 Codex++ 配置 Codex 入门教程
  • 终极指南:用pk3DS打造完全自定义的宝可梦3DS游戏体验
  • 海量简历筛选太痛苦?实测AI智能体批量归档黑科技,猎头效能提升10倍
  • 多通道高速采集的DDR瓶颈:你以为带宽够,其实差一个数量级
  • 攻防拐点:从“发现漏洞”到“机器速度修复”,解构 OpenAI 的网络安全新野心
  • HarmonyOS7 虚拟列表不卡顿的关键在哪?动态高度和多列布局这样封装
  • QY-18A、QY-18B、QY-18DL 和 QY-18DL-1 四种倾斜位移监测设备的参数对比及优劣
  • CoAP协议实战:从报文解析到工具链应用
  • LLM代码生成准确率已达89.7%(IEEE TSE 2024最新基准),但93%项目仍因这4个隐性缺陷失败
  • 群晖SSL证书:申请+部署+续期
  • Flowable UI实战:从零绘制一个BPMN标准请假审批流程图
  • 【技术解析】SimpleNet:在特征空间“制造”异常,实现高效图像缺陷检测与定位
  • HarmonyOS7 全局异常怎么兜底才靠谱?错误处理和降级架构这样搭
  • 从零到一:将OpenHarmony轻量内核移植到STM32F407的实践指南