mirai
supplies its own as.promise()
method, allowing it to be used as a promise from the promises
package.
These are next-generation, event-driven promises, developed in collaboration with Joe Cheng.
later
loop like other promises.A ‘mirai’ may be piped directly using the promise pipe &...>%
, which implicitly calls as.promise()
on the ‘mirai’. Similarly all promise-aware functions such as promises::then()
or shiny::ExtendedTask$new()
which take a promise can also take a ‘mirai’ (using promises
>= 1.3.0).
Alternatively, a ‘mirai’ may be explicitly converted into a promise by as.promise()
, which then allows using the methods $then()
, $finally()
etc.
The following example outputs “hello” to the console after one second when the ‘mirai’ resolves.
library(mirai)
library(promises)
p <- mirai({Sys.sleep(1); "hello"}) %...>% cat()
p
#> <Promise [pending]>
It is possible to both access a ‘mirai’ value at $data
and to use a promise for enacting a side effect (assigning the value to an environment in the example below).
env <- new.env()
m <- mirai({
Sys.sleep(1)
"hello"
})
promises::then(m, function(x) env$res <- x)
m[]
#> [1] "hello"
After returning to the top level prompt:
env$res
#> [1] "hello"
The code below is taken from the challenge to launch and collect one million promises. For illustration, the example is scaled down to ten thousand.
library(mirai)
daemons(8, dispatcher = "none")
#> [1] 8
r <- 0
start <- Sys.time()
m <- mirai_map(1:10000, \(x) x, .promise = \(x) r <<- r + x)
Sys.time() - start
#> Time difference of 2.722618 secs
later::run_now()
r
#> [1] 50005000
daemons(0)
#> [1] 0
The one million promises challenge took 6 mins 25 secs to complete using an Intel i7 11th gen mobile processor with 16GB RAM.