从R中实现的Promise中获取值

5

我读了许多关于Rpromises(包括这个)的文章,但仍然不明白。

看代码:

library(future)
library(promises)
plan(multiprocess)

read.csv.async <- function(file, header = TRUE, stringsAsFactors = FALSE) {
  future({
    read.csv(file, header = header, stringsAsFactors = stringsAsFactors)
  })
}

df_promise <- read.csv.async("https://rstudio.github.io/promises/data.csv")

df_promise %...>% filter(state == "NY")

df_filtered_promise <- df_promise %...>% filter(state == "NY")

df_filtered_promise

class(df_filtered_promise)

输出:

> read.csv.async <- function(file, header = TRUE, stringsAsFactors = FALSE) {
+   future({
+     read.csv(file, header = header, stringsAsFactors = stringsAsFactors)
+   })
+ }
> 
> df_promise <- read.csv.async("https://rstudio.github.io/promises/data.csv")
> 
> df_promise %...>% filter(state == "NY")
> 
> df_filtered_promise <- df_promise %...>% filter(state == "NY")
> 
> df_filtered_promise
<Promise [pending]>
> df_filtered_promise
<Promise [fulfilled: data.frame]>
> class(df_filtered_promise)
[1] "promise"

为什么fullfilledpromise没有返回其值?我该如何提取数据框架?


1
@r2evans 我不问future如何工作,而是promises - Taz
抱歉,我以为它们足够接近了,但你是对的,我匆忙了。 - r2evans
read.csv.async <- function(file, header = TRUE, stringsAsFactors = FALSE) { future({ read.csv(file, header = header, stringsAsFactors = stringsAsFactors) }) } df_promise <- read.csv.async("https://rstudio.github.io/promises/data.csv") df_promise %...>% filter(state == "NY") Error in df_promise %...>% filter(state == "NY") : could not find function "%...>%" - Daniel Fischer
@DanielFischer 只需添加 library(promises) - Taz
3
我发现他们的文档有些不完整:例如,我可以运行df_promise %...>% print()并将其打印出来,但我不想要它被打印,我想要它被实现/收集。我想知道 promises的意图是否完全不涉及用户交互,而是更多的是针对shiny(在其上表现良好)。 - r2evans
3个回答

9

有一种方法可以做到这一点,但是在我告诉你之前,我建议你不要在交互或脚本使用中使用 promises。同步编程比异步更方便,只有在非常重要的情况下不得不使用后者时(例如在 Shiny 中,如果您希望长时间操作运行时保持应用程序响应),才应该使用它。

如果选择使用 future,请尝试避免在其后链接任何%...>%操作,然后您可以简单地使用 future::value,就像 Daniel Fischer 所说的那样。

如果您决定完全使用 promises,并且将值提取到普通变量中对您很重要,则可以通过副作用来实现,就像这样的超级赋值:

df_filtered <- NULL
df_filtered_promise %...>% { df_filtered <<- . }

这将导致df_filtered变量在未来某个时间点被设置为df_filtered_promise的结果。(但如果出现错误,它将不会被赋值。)

通常情况下,在Shiny中不应该这样做,因为您通常希望将所有内容都包装在promise中,以便Shiny可以跟踪等待哪些操作的输出/观察器。


我建议您不要在交互或脚本使用中使用promises。它的复杂性确实令人望而生畏,我没有选择在脚本中使用它来“玩乐”。RLesur/crrri包依赖于promises,如果您想在脚本中提取html结果,则需要像这样做(我之所以来到这里,是因为我迫切希望返回/收集我的crri/promises html结果,而不使用超级/全局分配)。看起来这是我们现在能做的最好的事情。 - D. Woods

5

df <- environment(promise_object[["then"]])[["private"]][["value"]] 是您要查找的内容。

Promise对象以嵌套列表格式存储数据和属性,该列表是环境对象的一部分。


2
你好,欢迎来到 Stack Overflow!请参观一下 导览。感谢您的回答,但您能否添加一些解释说明您的代码是如何解决这个问题的呢?请查看 帮助中心 了解如何格式化代码的信息。 - Jeanne Dark

-2

你必须使用value函数:

value(df_filtered_promise)

2
不:> future::value(df_filtered_promise) Error in UseMethod("value") : no applicable method for 'value' applied to an object of class "promise" - Taz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接