You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular 8中联网恢复时重发失败的API请求?

处理网络中断导致的API请求失败重发方案

这是个非常常见的离线场景问题,我来给你梳理一套可落地的解决方案,核心思路就是先把失败请求存下来,等网络恢复后再自动重试,具体步骤如下:

1. 捕获并持久化失败请求

当API调用抛出网络相关异常(比如连接超时、Socket中断这类IOException)时,一定要把请求的关键信息持久化存储——别用内存存,重启APP就没了!建议用本地数据库(比如SQLite、Room)或者加密文件,存储的信息至少要包含:

  • 请求URL、HTTP方法(GET/POST/PUT等)
  • 请求体、请求头
  • 重试次数、创建时间
  • 唯一请求ID(用于幂等性校验)

举个Kotlin的示例代码:

// 定义失败请求的数据模型
data class FailedRequest(
    val id: String,
    val url: String,
    val method: String,
    val body: String?,
    val headers: Map<String, String>,
    val retryCount: Int,
    val createdAt: Long
)

// 捕获网络异常时保存请求
try {
    apiService.submitFormData(formData)
} catch (e: IOException) {
    // 判断是否是网络类异常(比如连接中断、无网络)
    if (isNetworkRelatedException(e)) {
        failedRequestDao.insert(FailedRequest(
            id = UUID.randomUUID().toString(),
            url = "https://your-api.com/submit",
            method = "POST",
            body = Gson().toJson(formData),
            headers = mapOf("Content-Type" to "application/json"),
            retryCount = 0,
            createdAt = System.currentTimeMillis()
        ))
    }
}

2. 监听网络状态变化

需要监听系统的网络状态,当网络从断开恢复到连接时,触发重试逻辑。不同平台有不同的实现方式:

  • Android:用ConnectivityManager.NetworkCallback监听网络切换
  • iOS:用NWPathMonitor监控网络路径变化
  • Web:监听online/offline事件

3. 重发失败请求并更新状态

网络恢复后,取出所有未处理的失败请求,逐个重试:

  • 重试成功:从存储中删除该请求,同时同步本地业务数据(比如标记提交状态为成功)
  • 重试失败:更新重试次数,超过最大重试阈值(比如3次)后,标记为“永久失败”,可以提示用户手动重试

示例重试逻辑:

fun retryAllFailedRequests() {
    val unresolvedRequests = failedRequestDao.getAllUnresolved()
    coroutineScope.launch(Dispatchers.IO) {
        unresolvedRequests.forEach { request ->
            try {
                val response = apiClient.sendRequest(
                    url = request.url,
                    method = request.method,
                    body = request.body,
                    headers = request.headers
                )
                if (response.isSuccessful) {
                    // 重试成功,删除记录
                    failedRequestDao.delete(request)
                    // 更新本地业务状态
                    updateLocalSubmissionStatus(request.id, isSuccess = true)
                } else {
                    // 非网络错误(比如400/500),根据业务决定是否继续重试
                    if (request.retryCount < 3) {
                        failedRequestDao.update(request.copy(retryCount = request.retryCount + 1))
                    } else {
                        // 超过重试次数,标记为失败
                        failedRequestDao.markAsPermanentFailure(request.id)
                    }
                }
            } catch (e: IOException) {
                // 还是网络问题,更新重试次数
                if (request.retryCount < 3) {
                    failedRequestDao.update(request.copy(retryCount = request.retryCount + 1))
                } else {
                    failedRequestDao.markAsPermanentFailure(request.id)
                }
            }
        }
    }
}

4. 关键注意事项

  • 幂等性必须保证:这是重中之重!重发请求可能导致重复提交,一定要给每个请求加唯一的Request-ID,后端根据这个ID判断是否已经处理过;或者用PUT代替POST(符合REST规范的场景),让后端执行更新而非创建操作。
  • 指数退避重试:别每次重试都立刻发,用指数退避策略(比如第一次等10s,第二次20s,第三次40s),避免给服务器造成压力。
  • 用户感知:可以在APP内加个轻量通知,告诉用户“有提交请求正在重试”;如果永久失败,弹窗提示用户手动重新提交。
  • 线程安全:所有持久化和重试操作都要在后台线程执行,别阻塞UI线程。

内容的提问来源于stack exchange,提问作者Rahul Dapke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:55:42