首页 > 解决方案 > 重新启动中断的 Promise 评估是否有问题?

问题描述

使用 创建一个承诺delayedAssign(),很容易构建一个可能导致restarting interrupted promise evaluation发出警告的场景。为什么在这种情况下会引发警告?此警告是否表明“不安全”的做法,或者这更像是“仅供参考”并且可以安全地忽略(即消音)?考虑以下示例:

counter <- 0L

make_val <- function() {

  if (counter < 1L) {
    counter <<- counter + 1L
    stop("insufficient count")
  }

  "yay!"
}

delayedAssign("foo", make_val())

foo
#> Error in make_val() : insufficient count

foo
#> [1] "yay!"
#> Warning message:
#> restarting interrupted promise evaluation

foo
#> [1] "yay!"

关闭此警告是否安全?还是应该避免重新启动中断的承诺评估?

get_foo <- function() {

  mute_ripe <- function(warn) {

    if (identical(conditionMessage(warn),
                  "restarting interrupted promise evaluation")) {

      invokeRestart("muffleWarning")
    }
  }

  tryCatch(
    withCallingHandlers(get("foo", envir = .GlobalEnv), warning = mute_ripe),
    error = function(err) NULL
  )
}

counter <- 1L
delayedAssign("foo", make_val())

get_foo()
#> NULL

get_foo()
#> [1] "yay!"

get_foo()
#> [1] "yay!"

标签: rpromisedelayed-execution

解决方案


我会保留该警告信息。考虑以下示例

counter <- 0L

make_val <- function() {
  counter <<- counter + 1L
  if (counter == 4L) {
    stop("somehow triggered an error halfway through")
  }
  counter
}

for (letter in letters[1:10]) {
    delayedAssign(letter, make_val())
}

a; b; c; d; e; f; g; h; i; j

在这里,我将在将来分配1:10给变量a-j。每个变量都依赖于状态,因为当且仅当成功评估先前的分配时,才会将值分配给变量(虽然不是推荐的做法)。如果在评估链的中途发生了某种错误,那么您可以看到评估在错误发生的地方停止。

> a; b; c; d; e; f; g; h; i; j
[1] 1
[1] 2
[1] 3

Error in make_val() : somehow triggered an error halfway through

但是,如果您重新运行代码,那么您可以成功完成每个分配,但您只会得到一组错误的结果。

> a; b; c; d; e; f; g; h; i; j
[1] 1
[1] 2
[1] 3
[1] 5
Warning message:
restarting interrupted promise evaluation 
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 11

如果没有这样的警告消息,那么我认为用户可能无法识别出这组错误结果的可能性非零,因为当他/她尝试重新运行代码进行调试时分配是无错误的。


推荐阅读