JmJ*_*JmJ 5 javascript promise ios swift
我正在从中执行JavaScript SDK JSContext,但是我无法从SDK的任何异步函数中获取值。我可以从中获得JavaScript许诺JSContext,但是我不知道如何解决它。我尝试了许多方法来从Promise中获得价值,但是每个方法都失败了。
如果我尝试以下操作,我会[object Promise]回来:
return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) })")!
Run Code Online (Sandbox Code Playgroud)
如果我then直接链接到JS,我[object Promise]仍然会:
return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300, () => resolve([1, 2, 3])) }).then(val => val.json())")
Run Code Online (Sandbox Code Playgroud)
如果我尝试从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!
Run Code Online (Sandbox Code Playgroud)
如果我在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!
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用顶级await并将Promise解析为一个变量,则将该变量从JSContextIU中拉出,将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")!
Run Code Online (Sandbox Code Playgroud)
在此先感谢您,如果我遗漏了一些东西,对Swift还是很新的。
在 JSContext 内模拟 Promise 工作流程时存在问题。setTimout、setInterval 等函数在 JSContext 中不可用。
但是,您可以通过将块传递到 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
502 次 |
| 最近记录: |