Giter VIP home page Giter VIP logo

Comments (5)

mhavu avatar mhavu commented on July 30, 2024 2

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()
})

from javascriptkit.

j-f1 avatar j-f1 commented on July 30, 2024

That would be a great feature to add! I would imagine it as either an overload of JSClosure.init that takes an async closure, or a separate JSClosure.async static method (for clarity) that does something like this:

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()
    }
}

from javascriptkit.

mhavu avatar mhavu commented on July 30, 2024

Indeed. If one doesn't need to return the result of the asynchronous call, using Task inside a JSClosure should work as it is, right? If this is the case, wrapping the asynchronous call (inside Task) to a synchronous function that calls a completion handler should do the trick when the result needs to be returned:

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.

from javascriptkit.

j-f1 avatar j-f1 commented on July 30, 2024

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 Task would work.

from javascriptkit.

mhavu avatar mhavu commented on July 30, 2024

Ah, too bad. Now that you mention it, it is clear that the closure can reach the return statement before the completion handler has set the result. Returning a JSPromise should work, though.

from javascriptkit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.