ios - 如何使用 JSObjectMakeDeferredPromise 从 Swift 调用 JavaScript 中返回承诺的函数
问题描述
我希望能够从返回承诺的 JSContext 调用函数。似乎 JSObjectMakeDeferredPromise 是执行此操作的机制,但文档太少,我不确定如何执行此操作。
谁能提供一个在返回承诺的 JSContext 中调用函数的示例?
解决方案
WebKit 是一个开源项目。我发现了与该功能相关的问题。这个函数更喜欢为未处理的 Promise 拒绝抛出异常。
所以你不能使用那个函数来返回一个承诺。但是JavaScriptCore 支持 Promise 关键字。我使用 Xcode 11.4.1 在 macOS 上运行此脚本。效果很好。
const promiseA = new Promise( (resolve, reject) => {
emulator.downloadWithHandler( (response) => {
var isFinish = response["isFinish"];
var isCancelled = response["isCancelled"];
var date = response["date"];
console.log("isFinish: " + isFinish);
console.log("isCancelled: " + isCancelled);
console.log("date: " + date);
if (isFinish || isCancelled) {
resolve(date);
}
});
});
这emulator.downloadWithHandler
是一个本机回调,将在某个时候在后台 DispatchQueue 上返回。如果您想使用该承诺并保留它。调用context.objectForKeyedSubscript("promiseA")
并包装它使用JSManagedValue
.
为 a 保留参考并没有多大用处Promise
。更重要的是如何访问JSContext
.
你可以调用 JSContext 的evaluateScript(_:)
. 如果您在脚本返回后保留上下文,则该上下文不会取消初始化并且可以使用。从上下文中获取对象,然后使用 JSValue 的invokeMethod(_:withArguments:)
或者call(withArguments:)
也可以工作。
NSHipster 有一篇关于该框架的精彩文章。你可以参考一下。
在我检查了文档和 iOS 13+ 新 API 之后。有什么可以确认的。那就是您可以使用JSObjectMakeDeferredPromise
create Promise
,这是 C 方式。为方便起见,我通过 Swift 方式创建所需的函数并导出到 C。所以答案是:
let context = JSContext()
var ref = context.jsGlobalContextRef
context.evaluateScript("function resolve(value) { console.log(value); };")
var resolve = context.objectForKeyedSubscript("resolve")?.jsValueRef
context.evaluateScript("function reject(reason) { console.log(reason); };")
var reject = context.objectForKeyedSubscript("reject")?.jsValueRef
var exception: JSValueRef?
var promise = JSObjectMakeDeferredPromise(ref, &resolve, &reject, &exception)
(lldb) po promise
▿ Optional<OpaquePointer>
▿ some : 0x000000010c74ae78
- _rawValue : (Opaque Value)
(lldb) p promise
(JSObjectRef?) $R4 = 0x000000010c74ae78
我不想深入研究。这只是意味着您可以将 JavaScriptCore 与 C 接口一起使用。并且JSValue
拥有 iOS 13+ 新的 C 风格的 init 方法.init(newPromiseIn:fromExecutor:)
。看起来一样,但我不太确定。
如果你坚持使用 C API。这篇文章可能会有所帮助。
PS该console.log
方法是手工原生导出日志的方法。
推荐阅读
- java - Eclipse 未在悬停时显示 javadocs,但在“在浏览器中打开附加的 javadocs”上显示它们
- android - UnityEngine.Videoplayer 不在 IOS 设备上渲染视频
- c - 奇怪的只读符号显示为 nm 中的初始化数据部分 (D)
- node.js - Discord.js:如果输入不是已知命令,我如何捕捉这种情况?
- c++ - CodeLite 显示不存在的错误 (wxWidgets)
- python - PLY :错过了“if”语句
- spring-boot - Maven 中依赖项的嵌套异常 - java.io.FileNotFoundException: ServerPropertiesAutoConfiguration.class
- java - JAVA - 获取最后打印文件的路径
- python-3.x - 无法在 Windows 10 中安装 argon2
- .net-core - .NET Core 3 Azure Function ILogger - 正确使用?