Maybe this is a bit of an old thread, but I found the perfect solution for me:
external val self: ServiceWorkerGlobalScope
fun runAsync(run: () -> Unit) {
var worker: Worker? = null
fun terminate() = worker!!.terminate()
worker = Worker(
URL.createObjectURL(
Blob(
arrayOf(
{
self.onmessage = {
run()
terminate()
}
}()
),
jsObject { type = "text/javascript" }
)
)
).apply {
postMessage(null)
}
}
This function can be used like this:
runAsync {
println("hello from async")
}
This can be improved as I do get a reference error that “kotlin isn’t found”, but the code successfully executes, so I think we can just catch this exception.
Anyways, hope this helps you!
Edit: actually, this doesn’t work perfectly… We need a way to pass in parameters to make it thread safe
Edit 2: Okay, I’ve been looking into it, but it’s harder than expected. I tried converting GitHub - boneVidy/inline-webworker: inline webworker this typescript library to Kotlin, but I ran into some issues. For instance, the tasks function task: Function needs a reference to self: InlineWorker so it can run postMessage (compared to the TS I see it like this typealias Function = (self: InlineWebWorker) -> Unit), but when I provide task() with this to put in the blob array arrayOf({ task(self = this) }()), then the task function already gets executed on this thread instead of on the second thread like how it’s supposed to work.
Basically, the only way my example above works is because I assign the function to self.onmessage and thus the function only gets executed when onmessage fires on the second thread. So yeah, any ideas would be welcome.
Edit 3: Added terminate() to example
Edit 4: I don’t think this is working at all as my page still gets stuck executing it…
There is this GitHub - korlibs/kworker: Portable Workers for Multiplatform Kotlin 1.3 library but it’s not finished and doesn’t work on browser only without removing the cluster dependency in the code. It works, but only for small stuff. See, only certain types are allowed to be pushed as messages, only Ints, Doubles, Strings and ByteArrays are allowed. So to push a large number of objects, they need to be converted to JSON or something, making it slower than simply running it on the main thread… There is a way to use transferable objects in JS that somehow passes the reference to an object in a message, but KWorker doesn’t support this I think. Plus this is hard already in JS, let alone Kotlin/JS.
This just needs an easy to use lbrary or something as it’s getting ridiculous how difficult this is.