Closed MihaelIsaev closed 1 year ago
I just tried to use JSClosure.async
which doesn't work.
Code inside of Task
inside of synchronous JSClosure
doesn't work also. (it is same as JSClosure.async
)
Then I tried to create new carton project just to check if it works there, but unfortunately it doesn't.
The only place where Task
works is
static func main() async {
Task {
print("🔆🔆🔆🔆🔆🔆") // works
}
}
But it never works anywhere later.
And btw it throws this in the WebInspector console
Not sure if I'm missing something. @kateinoigakukun please help 🙏
One more example
import JavaScriptKit
@main
public struct CartonApp {
public private(set) var text = "Hello, World!"
public static func main() async {
print(CartonApp().text)
if let docObj = JSObject.global.document.object, let bodyObj = JSObject.global.document.jsValue.body.object {
var button = JSObject.global.document.createElement.function?.callAsFunction(this: docObj, "button").jsValue
button?.innerText = "Click me".jsValue
JSObject.global.document.jsValue.body.appendChild.function?.callAsFunction(this: bodyObj, button)
if let buttonObj = button?.object {
button?.addEventListener.function?.callAsFunction(this: buttonObj, "click", JSClosure({ args in
print("clicked") // works
Task {
print("clicked inside of Task") // never called
}
return .undefined
}))
}
}
}
}
JSClosure.async
doesn't work at all
button?.addEventListener.function?.callAsFunction(this: buttonObj, "click", JSClosure.async({ args in
print("clicked async") // never called
return .undefined
}))
Thanks for reporting. This code however won't run as you expect, even on macOS:
@main public struct CartonApp { public private(set) var text = "Hello, World!" public static func main() { print(CartonApp().text) Task { print("async Task works") // this never calls } } }
Expected behavior
async Task works
should be printed into console
It's a misunderstanding of the main function's lifetime. Once you start the task, the synchronous context reaches its end and there's nothing telling it to keep alive.
On other platform you can use CFRunLoopRun()
to signal 'keep my process alive', but that's not supported in SwiftWasm.
The correct way to achieve that for the main function would be changing the signature from public static func main()
to public static func main() async
, remove the task and directly use async code. This is supported in latest SwiftWasm toolchains.
@yonihemi Thank you for the reply. Could you please help with JSClosure.async
? It doesn't work.
import JavaScriptKit
@main
public struct CartonApp {
public private(set) var text = "Hello, World!"
public static func main() async {
print(CartonApp().text)
if let docObj = JSObject.global.document.object, let bodyObj = JSObject.global.document.jsValue.body.object {
var button = JSObject.global.document.createElement.function?.callAsFunction(this: docObj, "button").jsValue
button?.innerText = "Click me".jsValue
JSObject.global.document.jsValue.body.appendChild.function?.callAsFunction(this: bodyObj, button)
if let buttonObj = button?.object {
button?.addEventListener.function?.callAsFunction(this: buttonObj, "click", JSClosure.async({ args in
print("clicked async") // never called
return .undefined
}))
}
}
}
}
I don't see calls to JavaScriptEventLoop.installGlobalExecutor()
in your sample code, per JSKit documentation in its README.md
.
That's awesome, that's exactly what I missed!🔥 Thank you very much for pointing me @MaxDesiatov I appreciate it!
Description
I'm trying to execute async code wrapped into
Task
but it never called.Steps to reproduce
carton init
Expected behavior
async Task works
should be printed into consoleEnvironment
@kateinoigakukun