Adam S
06/28/2023, 7:56 AMexpect suspend fun to get the result from each target. But because it’s an external interface I can’t add suspend, and I can’t use runBlocking {} because it’s not available for JS…Dmitry Khalanskiy [JB]
06/28/2023, 7:58 AMGlobalScope.launch {}, but it does not wait for the code in the block to finish.Adam S
06/28/2023, 8:00 AMlaunch {} returns a Job, but the function needs it to return a StringDmitry Khalanskiy [JB]
06/28/2023, 8:02 AMAdam S
06/28/2023, 8:10 AMAdam S
06/28/2023, 8:11 AMDmitry Khalanskiy [JB]
06/28/2023, 8:13 AMAdam S
06/28/2023, 8:17 AMDmitry Khalanskiy [JB]
06/28/2023, 8:18 AMAdam S
06/28/2023, 8:19 AMthis is an inherent limitation in JSI’m not a JS developer, but surely there’s a way that JS code deals with this problem? I’m not necessarily looking for an equivalent to
runBlocking {}, but even if there’s a JS-specific function that can bridge blocking/non-blocking then I could change
expect suspend fun getData(): String
to
expect fun getData(): String
and then use runBlocking {} on JVM/Native, and something else on JSAdam S
06/28/2023, 8:21 AMDo you mean, to the issue? I’m pretty sure it won’t change anything.I’d prefer to make a new issue, but if it can’t be done then all I can do is make a comment and stop working on my library
Dmitry Khalanskiy [JB]
06/28/2023, 8:25 AMsurely there’s a way that JS code deals with this problemIt does it by working with the equivalent of
suspend functions. JS code is single-threaded, and fun getData(): String, since it's not a suspend fun, has to all happen in the same thread. While await() is waiting, the thread can't do anything else. On JS, since this is the only thread, getData has no chance to run.Dmitry Khalanskiy [JB]
06/28/2023, 8:26 AMsuspend functions are abstractions over those.Dmitry Khalanskiy [JB]
06/28/2023, 8:28 AMasync functions actually, a direct equivalent of suspend functions, and there, you have the exact same inherent problem. https://stackoverflow.com/a/41976799 EDIT: wrong linkAdam S
06/28/2023, 8:29 AMWhileIf I could changeis waiting, the thread can’t do anything else.await()
expect suspend fun getData(): String to expect fun getData(): String, then doesn’t that mean I wouldn’t need an await()?Adam S
06/28/2023, 8:30 AMDmitry Khalanskiy [JB]
06/28/2023, 8:31 AMgetData is probably a recursive function. You probably want to rename expect suspend fun getData(): String to expect suspend fun getDataImpl(): String or something like that.Dmitry Khalanskiy [JB]
06/28/2023, 8:32 AMexpect suspend fun getDataImpl(): String becomes expect fun getDataImpl(): String, then you can implement your interface as just override fun getData() = getDataImpl().Adam S
06/28/2023, 8:32 AM// src/commonMain/kotlin/MyCommonClass.kt
import x.y.z.ThirdPartyInterface
class MyCommonClass : ThirdPartyInterface {
override fun getData(): String = platformGetData()
}
expect suspend fun platformGetData(): StringDmitry Khalanskiy [JB]
06/28/2023, 8:33 AMsuspend function from a non-suspend one and obtain its result, it's not possible.Dmitry Khalanskiy [JB]
06/28/2023, 8:34 AMAdam S
06/28/2023, 8:44 AMAdam S
06/28/2023, 8:44 AMAdam S
06/28/2023, 8:46 AMThe way JavaScript runs on a given thread is that it processes a queue
of jobs:
1. Pick up the next pending job
2. Synchronously execute the code for that job
3. Only when that job completes go back to Step 1 to pick up the next job
(It’s a bit more complicated than that, there are two levels to it, but that’s not relevant to this particular question.)
XHR completions and such are jobs that get scheduled in the queue.
There is no way to pause a job, run another job from the queue, and
then pick up the paused job. `async`/`await` provides dramatically
simpler syntax for handling asynchronous operations, but they don’t
change the nature of the job queue.could Kotlin implement its own task queue that allows for pausing jobs?
Dmitry Khalanskiy [JB]
06/28/2023, 8:48 AMAdam S
06/28/2023, 9:06 AM