Skip to content

Commit 4eb8c5f

Browse files
committed
Add duration measurement to AsyncCallbacks
Closes #820
1 parent 12c6a48 commit 4eb8c5f

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package japgolly.scalajs.react
33
import japgolly.scalajs.react.internal.{RateLimit, SyncPromise, Timer, catchAll, identityFn, newJsPromise}
44
import java.time.Duration
55
import scala.collection.compat._
6-
import scala.concurrent.duration.FiniteDuration
6+
import scala.concurrent.duration.{FiniteDuration, MILLISECONDS}
77
import scala.concurrent.{ExecutionContext, Future}
88
import scala.scalajs.js
99
import scala.scalajs.js.{Thenable, timers, |}
@@ -826,4 +826,30 @@ final class AsyncCallback[A] private[AsyncCallback] (val completeWith: (Try[A] =
826826
def fork_ : Callback =
827827
delayMs(1).toCallback
828828

829+
/** Record the duration of this callback's execution. */
830+
def withDuration[B](f: (A, FiniteDuration) => AsyncCallback[B]): AsyncCallback[B] = {
831+
val nowMS: AsyncCallback[Long] = CallbackTo.currentTimeMillis.asAsyncCallback
832+
for {
833+
s <- nowMS
834+
a <- self
835+
e <- nowMS
836+
b <- f(a, FiniteDuration(e - s, MILLISECONDS))
837+
} yield b
838+
}
839+
840+
/** Log the duration of this callback's execution. */
841+
def logDuration(fmt: FiniteDuration => String): AsyncCallback[A] =
842+
withDuration((a, d) =>
843+
Callback.log(fmt(d)).asAsyncCallback ret a)
844+
845+
/** Log the duration of this callback's execution.
846+
*
847+
* @param name Prefix to appear the log output.
848+
*/
849+
def logDuration(name: String): AsyncCallback[A] =
850+
logDuration(d => s"$name completed in $d.")
851+
852+
/** Log the duration of this callback's execution. */
853+
def logDuration: AsyncCallback[A] =
854+
logDuration("AsyncCallback")
829855
}

doc/changelog/1.7.7.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ This entire release is focused on `AsyncCallback`.
1111

1212
`fork_` on the other hand, returns nothing and is effectively fire-and-forget.
1313

14+
* Added duration measuring methods that exist on `Callback`:
15+
16+
```scala
17+
def withDuration[B](f: (A, FiniteDuration) => AsyncCallback[B]): AsyncCallback[B]
18+
def logDuration (fmt: FiniteDuration => String) : AsyncCallback[A]
19+
def logDuration (name: String) : AsyncCallback[A]
20+
def logDuration : AsyncCallback[A]
21+
```
22+
1423
* `AsyncCallback` object:
1524

1625
* Added `def awaitAll(as: AsyncCallback[_]*): AsyncCallback[Unit]` to wait for a number of async processes to complete.

0 commit comments

Comments
 (0)