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

如何用Combine实现等待WebSocket连接状态变更后执行请求?

解决方案

可以利用Combine的first(where:)操作符结合async/await的values属性实现该逻辑,让调用者无需提前检查连接状态,直接调用方法即可。

实现思路

  1. 直接处理当前状态:若已连接则执行请求,若未连接直接抛出异常
  2. 若处于连接中状态,监听connectionStatus发布者,等待第一个非连接中的状态(connected或notConnected)
  3. 根据最终状态决定继续执行请求或抛出异常

完整代码示例

假设ConnectionStatus枚举定义如下:

enum ConnectionStatus {
    case notConnected
    case connecting
    case connected
}

class WebSocketManager {
    @Published private(set) var connectionStatus: ConnectionStatus = .notConnected
    
    func sendRequest() async throws -> String { // 示例返回类型,可按需调整
        // 处理当前已是最终状态的情况
        switch connectionStatus {
        case .connected:
            return try await performRequest()
        case .notConnected:
            throw NSError(domain: "WebSocketError", code: -1, userInfo: [NSLocalizedDescriptionKey: "未连接到服务器"])
        case .connecting:
            break // 进入等待逻辑
        }
        
        // 等待连接状态变为connected或notConnected
        guard let finalStatus = await connectionStatus
            .publisher
            .first(where: { $0 != .connecting })
            .values
            .first(await: .distantFuture) else {
            throw NSError(domain: "WebSocketError", code: -2, userInfo: [NSLocalizedDescriptionKey: "等待连接状态超时"])
        }
        
        // 根据最终状态处理
        switch finalStatus {
        case .connected:
            return try await performRequest()
        case .notConnected:
            throw NSError(domain: "WebSocketError", code: -1, userInfo: [NSLocalizedDescriptionKey: "未连接到服务器"])
        case .connecting:
            // 理论上不会触发,已被first(where:)过滤
            throw NSError(domain: "WebSocketError", code: -3, userInfo: [NSLocalizedDescriptionKey: "连接状态异常"])
        }
    }
    
    // 实际执行WebSocket请求的私有方法
    private func performRequest() async throws -> String {
        // 此处编写发送请求、处理响应的逻辑
        return "请求成功响应"
    }
}

关键细节说明

  • connectionStatus.publisher获取发布者,first(where:)过滤掉.connecting状态,只接收我们需要的最终状态
  • .values将Combine发布者转换为async序列,first(await:)用于等待第一个符合条件的值(.distantFuture表示无超时,可按需设置具体超时时间)
  • 调用者只需直接调用sendRequest(),方法内部自动处理状态等待、异常抛出逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:27:35