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"
A mirai_map
also has an as.promise()
method, which allows it to be used directly in a Shiny ExtendedTask.
The implementation uses promises::promise_all()
, and will resolve when the entire map operation completes or at least one mirai in the map is rejected.
The following example prints the list 1, 2, 3 to the console after the flatmap returns a vector of the same values.
library(mirai) library(promises) with(daemons(2), { mp <- mirai_map(1:3, function(x) { Sys.sleep(x); x }) mp %...>% print mp[.flat] }) #> [1] 1 2 3 #> [[1]] #> [1] 1 #> #> [[2]] #> [1] 2 #> #> [[3]] #> [1] 3
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 = FALSE) #> [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 3.441591 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.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.