-
-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Asynchronous calls in JSClosure #157
Comments
That would be a great feature to add! I would imagine it as either an overload of static func async(_ body: @escaping ([JSValue]) async throws -> JSValue) -> JSClosure {
JSClosure { arguments in
JSPromise { resolver in
Task {
do {
let result = try await body(arguments)
resolver(.success(result))
} catch {
if let jsError = error as? JSError {
resolver(.failure(jsError.jsValue()))
} else {
resolver(.failure(JSError(message: String(describing: error)).jsValue()))
}
}
}
}.jsValue()
}
} |
Indeed. If one doesn't need to return the result of the asynchronous call, using let closure = .object(JSClosure { (arguments: [JSValue]) in
guard let url = arguments.first?.string else {
return JSValue.undefined
}
func wrappedFetch(_ url: String, completion: @escaping (String) -> ()) {
Task {
let data = await fetch(url)
completion(data)
}
}
var result: String
wrappedFetch(url) { data in
result = data
}
return result
}) What you suggest above would definitely be cleaner. |
I don’t think that code would work. Specifically, I get two compiler errors: “Variable 'result' captured by a closure before being initialized” and “Variable 'result' used before being initialized.” However, you’re correct that if you don’t need to return the result of the asynchronous call (and if you don’t need the JS code to be able to wait for your code to finish running), running the async code in a |
Ah, too bad. Now that you mention it, it is clear that the closure can reach the |
This does indeed work: let closure = .object(JSClosure { (arguments: [JSValue]) in
guard let url = arguments.first?.string else {
return JSValue.undefined
}
func wrappedFetch(_ url: String, completion: @escaping (String) -> ()) {
Task {
let data = try await fetch(url)
completion(data)
}
}
let result = JSPromise { resolve in
wrappedFetch(url) { data in
resolve(.success(data))
}
}
return result.jsValue()
}) |
What is the best way to handle calls to asynchronous code inside a
JSClosure
, especially if one needs to return the result of such call from theJSClosure
? Consider the following example:This results in the following error:
The reason is obvious, but is there a nice way to work around this?
The text was updated successfully, but these errors were encountered: