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(): String
Dmitry 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