[求助] HarmonyOS鸿蒙Next中runJavaScript运行异步JS代码的结果获取
[求助] HarmonyOS鸿蒙Next中runJavaScript运行异步JS代码的结果获取 我有一段JavaScript代码(省略细节)如下
function waitForValue() {
return new Promise((resolve, reject) => {...});
}
(async () => {
try {
const val = await waitForValue();
return val;
} catch (e) {
console.error(e);
}
})();
经浏览器测试可以正常工作。但是在ArkTS中
this.webviewController.runJavaScript(code)
.then((resolvedResult) => {console.log(resolvedResult);})
在控制台打印出来的是null。请问如何解决?
更多关于[求助] HarmonyOS鸿蒙Next中runJavaScript运行异步JS代码的结果获取的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你好,runJavaScript 执行的js方法,如果是异步方法将无法获取返回值。
可以借助 javaScriptProxy 代理对象来获取异步方法的执行结果。
大致思路是:
1、注册代理对象,名为testObjName,该对象有一个test方法。
2、执行异步js方法的结果val, 作为test方法的参数传递。
3、在test方法中获取执行结果。
import { webview } from '@kit.ArkWeb';
class TestClass {
test(param: ESObject): void {
console.log(param) // xianyin
}
}
@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: TestClass = new TestClass();
build() {
Column() {
Button('run')
.onClick(() => {
this.onRun()
})
Web({ src: $rawfile('index.html'), controller: this.webviewController })
.javaScriptProxy({
object: this.testObj,
name: "testObjName",
methodList: ["test"],
controller: this.webviewController,
})
}
.margin({ top: 100 })
}
onRun() {
const js = `
function waitForValue() {
return new Promise((resolve, reject) => { return resolve('xianyin') });
}
(async () => {
const val = await waitForValue();
testObjName.test(val)
})()
`
this.webviewController.runJavaScript(js) //执行结果在test()中返回
}
}
更多关于[求助] HarmonyOS鸿蒙Next中runJavaScript运行异步JS代码的结果获取的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
数据传递建议使用序列化成JSON字符串的形式,然后再使用console.log()进行打印,若数据传输正常,再使用反序列化拿到数据;
JSON.stringify(data);//序列化成JSON字符串进行数据传输
JSON.parse(dataJson); //反序列后拿到数据
Webview的runJavaScript和runJavaScriptExt二者均可异步执行JavaScript脚本,并通过回调或Promise返回执行结果。
区别上讲,runJavaScript返回脚本执行的结果只能是string,而runJavaScriptExt可以返回的类型支持JsMessageType,包括字符串、数组类型等。
另外,如果这个HTML是你自己的项目,建议将复杂的js代码直接封装到HTML页面中,只暴露出函数名就行了,然后runJavaScript 的时候就轻松多了!
经过测试我推测runJavaScript的回调在JS同步执行完后就触发了,等不到异步的结果(但我未在官方文档中找到相关说明) 你能不能给一个成功执行异步JavaScript的完整例子?谢谢!
在HarmonyOS Next中,使用runJavaScript执行异步JavaScript代码时,可通过JavaScriptResult回调获取结果。异步操作需在JS代码中返回Promise,系统会等待Promise解析后,在回调中返回最终结果或错误。
在HarmonyOS Next中,WebviewController.runJavaScript() 方法默认返回的是所执行脚本中 最后一条表达式 的值。你的异步JavaScript代码是一个立即执行的异步函数表达式(IIFE),它返回的是一个Promise对象,但runJavaScript并不会自动等待这个Promise完成并解析其最终值。
要获取异步JavaScript代码的最终结果,你需要让脚本明确地返回一个Promise,并且ArkTS端需要处理这个Promise的解析。具体方法如下:
1. 修改JavaScript代码,使其返回一个可被runJavaScript处理的Promise:
将你的代码包装成一个明确返回Promise的函数,并确保这个Promise是脚本的最终返回值。
// 修改后的JavaScript代码
function waitForValue() {
return new Promise((resolve, reject) => {...});
}
// 关键:返回一个Promise,该Promise最终解析为你想要的值
return (async () => {
try {
const val = await waitForValue();
return val; // 这个val将成为最终Promise的解析值
} catch (e) {
console.error(e);
throw e; // 或者返回一个错误标识,取决于你的错误处理逻辑
}
})();
2. 在ArkTS中,runJavaScript的返回值将是一个Promise,你需要对其进行链式处理:
this.webviewController.runJavaScript(modifiedCode)
.then((jsPromise: Promise<Object>) => {
// runJavaScript返回的是JS端的Promise对象
return jsPromise; // 将其返回,进行下一级then处理
})
.then((resolvedValue: Object) => {
// 这里得到的才是异步JS代码中await waitForValue()最终解析出来的val
console.log('最终结果:', resolvedValue);
})
.catch((error: Error) => {
console.error('执行失败:', error);
});
原理说明:
runJavaScript执行脚本,并捕获脚本最后求值的结果。- 如果你的脚本最终求值结果是一个Promise,
runJavaScript返回的Promise(ArkTS端)会解析为这个JavaScript Promise对象。 - 你需要再次调用
.then来订阅这个JavaScript Promise的解析结果,从而获取到内部异步操作(waitForValue())的实际返回值。
简洁写法:
你也可以将两步合并,因为runJavaScript返回的Promise解析后就是JS端的Promise。
this.webviewController.runJavaScript(modifiedCode)
.then((jsPromise: Promise<Object>) => jsPromise)
.then((finalValue: Object) => {
console.log('获取到的值:', finalValue);
});
确保你的JavaScript代码字符串 (modifiedCode) 最终是一个返回Promise的表达式或语句。这样就能正确获取到异步操作的结果,而不是null。

