altavir
01/19/2019, 9:10 AMrunTest
and sadly, it does not solve the problem with "blocking" calls in JS (also it could be run only from test). I am still thinking if it is really necessary. My use case is that I have an interface with a regular blocking function and implementation which utilizes coroutines for parallel computations. Currently I can't do it since I can't collect parallel elements in a non-blocking way. Maybe there are better ways.Ilmir Usmanov [JB]
01/21/2019, 11:17 AMan interface with a regular blocking function
can't do it since I can't collect parallel elements in a non-blocking way.If I understood you correctly, the code looks like
interface A {
fun doSomething(): Long
}
class B: A, CoroutineScope {
override fun doSomething(): Long {
val jobs = arrayListOf<Deferred<Long>>()
for (i in 0..100) jobs += async {
// some computation
1L
}
var result: Long = 0
runBlocking {
result = jobs.awaitAll().reduce { acc, l -> acc + l }
}
return result
}
override val coroutineContext = Dispatchers.Default
}
And you want to replace runBlocking
with something, that works on all platforms?altavir
01/21/2019, 11:25 AMaltavir
01/21/2019, 11:36 AMCompletableDeferred
that I can't use to immediately get result from blocking code.Vsevolod Tolstopyatov [JB]
01/21/2019, 12:10 PMrunBlocking
is impossible to implement on JS due to limitations of the JS runtime itself.
Not only promises and timeouts, but inability to advance current event loop is the main issue.
What you can do though is the following:
1) Write your own event loop (or copy one from kotlinx.coroutines
), optionally prohibit calls to delay
and promise
using some global variable
2) Launch all parallel computations from within this event loop. In order to achieve parallelism on JVM, explicitly specify dispatcher:
suspend expect fun dispatcher()
// Jvm
actual fun dispatcher() = your jvm dispatcher
// Js
actual suspend fun dispatcher() = coroutineContext[CoroutineInterceptor]!!
// Usage
var result: Long = 0
runEventLoop {
val jobs = arrayListOf<Deferred<Long>>()
for (i in 0..100) jobs += async(dispatcher()) {
// some computation
1L
}
result = jobs.awaitAll().reduce { acc, l -> acc + l }
}
return result
altavir
01/21/2019, 12:14 PMaltavir
01/21/2019, 12:14 PMVsevolod Tolstopyatov [JB]
01/21/2019, 12:20 PMeventLoop
, but was able to find solution for each 🙂
Could you please create an issue with your specific use-case?altavir
01/21/2019, 12:21 PMaltavir
01/21/2019, 1:01 PM