Skip to content

Commit f33f229

Browse files
committed
Add AsyncCallback.{traverse,sequence}_
Closes #807
1 parent 89ab017 commit f33f229

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

core/src/main/scala/japgolly/scalajs/react/AsyncCallback.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,43 @@ object AsyncCallback {
171171
def sequenceOption[A](oca: => Option[AsyncCallback[A]]): AsyncCallback[Option[A]] =
172172
traverseOption(oca)(identityFn)
173173

174+
/** Same as [[traverse()]] except avoids combining return values. */
175+
def traverse_[T[X] <: IterableOnce[X], A, B](ta: => T[A])(f: A => AsyncCallback[B]): AsyncCallback[Unit] =
176+
AsyncCallback.byName {
177+
val as = new js.Array[A]
178+
for (a <- ta.iterator)
179+
as.push(a)
180+
181+
as.length match {
182+
case 0 => AsyncCallback.unit
183+
case 1 => AsyncCallback.byName(f(as(0))).void
184+
case n =>
185+
val latch = countDownLatch(n).runNow()
186+
187+
for (a <- as)
188+
AsyncCallback.byName(f(a))
189+
.finallyRunSync(latch.countDown)
190+
.runNow()
191+
192+
latch.await
193+
}
194+
}
195+
196+
/** Same as [[sequence()]] except avoids combining return values. */
197+
def sequence_[T[X] <: IterableOnce[X], A](tca: => T[AsyncCallback[A]]): AsyncCallback[Unit] =
198+
traverse_(tca)(identityFn)
199+
200+
/** Same as [[traverseOption()]] except avoids combining return values. */
201+
def traverseOption_[A, B](oa: => Option[A])(f: A => AsyncCallback[B]): AsyncCallback[Unit] =
202+
AsyncCallback.delay(oa).flatMap {
203+
case Some(a) => f(a).void
204+
case None => AsyncCallback.unit
205+
}
206+
207+
/** Same as [[sequenceOption()]] except avoids combining return values. */
208+
def sequenceOption_[A](oca: => Option[AsyncCallback[A]]): AsyncCallback[Unit] =
209+
traverseOption_(oca)(identityFn)
210+
174211
def fromFuture[A](fa: => Future[A])(implicit ec: ExecutionContext): AsyncCallback[A] =
175212
AsyncCallback(f => Callback {
176213
val future = fa

doc/changelog/1.7.7.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ This entire release is focused on `AsyncCallback`.
2525
}
2626
```
2727

28+
* You can now add a `_` suffix to the following to return an `AsyncCallback[Unit]` and be more efficient under-the-hood:
29+
30+
* `traverse`
31+
* `sequence`
32+
* `traverseOption`
33+
* `sequenceOption`
34+
2835
* `AsyncCallback.Barrier`:
2936

3037
* Added `isComplete: CallbackTo[Boolean]` to synchronously query whether the barrier is complete or not.

0 commit comments

Comments
 (0)