如何在R中对同一函数调用进行N次tryCatch重试?
实现N次重试的解决方案
一、Base R自定义重试函数
Base R没有内置的重试功能,但可以自己封装一个通用的重试函数,实现对任意函数的N次重试逻辑。以下是针对googlesheets4::sheet_write()的实现示例:
retry_fn <- function(fn, max_tries = 3, ...) { attempt <- 1 while(attempt <= max_tries) { cat(sprintf("第%d次尝试\n", attempt)) result <- tryCatch({ fn(...) return(invisible(NULL)) }, error = function(e) { cat(sprintf("尝试失败:%s\n", e$message)) if(attempt == max_tries) { stop(sprintf("已达到最大重试次数(%d),操作失败", max_tries)) } Sys.sleep(1) attempt <<- attempt + 1 }) } } # 使用示例:设置重试3次 retry_fn( fn = googlesheets4::sheet_write, max_tries = 3, data = our_df, ss = our_spreadsheet, sheet = 'our_sheetname' )
这个函数会循环执行目标函数,失败后记录次数,直到成功或达到最大重试次数。可以根据需求添加延迟逻辑(如Sys.sleep()),避免短时间内重复请求引发的问题。
二、第三方库实现重试
如果不想手动编写逻辑,可以使用专门处理重试的R包:
1. retry包
retry包提供了简洁的重试接口,支持设置重试次数、延迟、成功条件等:
先安装并加载包:
install.packages("retry") library(retry)
实现N次重试:
retry( expr = googlesheets4::sheet_write(data = our_df, ss = our_spreadsheet, sheet = 'our_sheetname'), times = 3, delay = 1, silent = FALSE )
实现无限重试,可将times设为Inf,同时指定成功判断条件:
retry( expr = googlesheets4::sheet_write(data = our_df, ss = our_spreadsheet, sheet = 'our_sheetname'), times = Inf, delay = 2, until = function(x) inherits(x, "NULL") )
2. purrr包结合循环
如果使用tidyverse生态,可通过purrr::possibly()结合循环实现重试:
library(purrr) safe_sheet_write <- possibly(googlesheets4::sheet_write, otherwise = NULL) # 重试3次 result <- map(1:3, ~{ cat(sprintf("第%d次尝试\n", .x)) res <- safe_sheet_write(data = our_df, ss = our_spreadsheet, sheet = 'our_sheetname') if(!is.null(res)) return(res) Sys.sleep(1) }) if(all(map_lgl(result, is.null))) { stop("所有重试均失败") }
三、总结
- Base R无内置重试功能,需自行封装
tryCatch+循环的逻辑; - 第三方库如
retry可快速实现N次或无限重试,代码更简洁; - 无限重试需谨慎使用,建议添加延迟和退出条件(如超时自动停止),避免死循环。
内容的提问来源于stack exchange,提问作者Canovice
相关产品推荐
相关产品推荐

