javascript - 从 JSContext 中的 JS Promise/async 函数获取值

标签 javascript ios swift promise

我正在从 JSContext 中执行一个 JavaScript SDK,但是我无法从 SDK 的任何异步函数中获取值。我可以从 JSContext 中获得 JavaScript promise,但我不知道如何解决它。我尝试了多种方法来从 Promise 中获取值,但每一种都失败了。

如果我尝试类似下面的操作,我会返回 [object Promise]:

return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) })")!

如果我将 then 直接链接到 JS,我仍然得到 [object Promise]:

return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) }).then(val => val.json())")

如果我尝试从 Swift 调用该方法,我仍然会得到 [object Promise]:

let jsPromise = self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) })")
let promiseResult = jsPromise?.invokeMethod("then", withArguments: ["val => { return val.json() }"])
return promiseResult!

如果我在 Promise 之外声明一个 JS 变量,然后将值从 Swift 调用的 then 调用传递给它,我会得到设置给它的原始值(如预期但值得一试):

self.jsContext.evaluateScript("let tempVar = 'Nothing has happened yet!'")
let jsPromise = self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) })")
let promiseResult = jsPromise?.invokeMethod("then", withArguments: ["val => { tempVar = val }"])
let tempVar = self.jsContext.evaluateScript("tempVar")
return tempVar!

如果我尝试使用顶级 await 并将 Promise 解析为一个变量,然后将该变量从 JSContext 中拉出,我会得到一个 EXC_BAD_INSTRUCTION 错误:

let jsPromise = self.jsContext.evaluateScript("let someVar = await new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) })")
return self.jsContext.evaluateScript("someVar")!

提前致谢,如果我遗漏了什么,对于 Swift 来说仍然很新。

最佳答案

在 JSContext 中模拟 Promise 工作流时出现问题。 JSContext 中没有setTimout、setInterval 等函数。

但是,您可以通过将 block 传递到 JSContext 来从 Javascript 调用 Swift 代码。这是一个代码片段,展示了如何找出 JSContext 中的错误。

var logValue = "" {
    didSet {
        print(logValue)
    }
}
//block we can pass to JSContext as JS function
let showLogScript: @convention(block) (String) -> Void = { value in
    logValue = value
}
let jsContext = JSContext()

//set exceptionHandler block
jsContext?.exceptionHandler = {
    (ctx: JSContext!, value: JSValue!) in
    print(value)
}
//make showLog function available to JSContext
jsContext?.setObject(unsafeBitCast(showLogScript, to: AnyObject.self), forKeyedSubscript: "showLog" as (NSCopying & NSObjectProtocol))

jsContext!.evaluateScript("showLog('this is my first name')") //this works
jsContext!.evaluateScript("showLog(setTimeout.name)") //it has issue

关于javascript - 从 JSContext 中的 JS Promise/async 函数获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46181856/

相关文章:

iphone - 什么决定了 CALayer.position 的初始值?

ios - AVCapturePhotoOutput jpegPhotoDataRepresentation 访问预览照片

javascript - AngularJS 从 Javascript 调用 Controller 函数

javascript - 如何通过 Javascript formData API 发送变量

ios - SPP 配置文件蓝牙 iOS

android - 测量单个 GUI 元素的加载时间

javascript - 如何使用mailapp发送图像和图表?

javascript - jQuery 只处理第二次点击

ios - 我无法快速从本地服务器加载视频文件

swift 3 : Type error of generic delegate type with concrete consumer type