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

如何在PromiseKit链式请求的done块中获取首个请求的userModel(不存self)

解决Promise链中跨块传递数据的问题

你遇到的核心问题是在Promise链式调用中需要保留之前步骤的结果,同时不想依赖实例变量来存储。其实用**元组+Promise.value()**来包装同步数据是完全合理的方案,这正是Promise链中传递多份上下文数据的标准做法,不用觉得别扭~

下面是修改后的代码,完全移除了self.userModel和self.initModel的使用,通过在每个then块中返回包含所需数据的元组来传递上下文:

func callService(completionHandler: @escaping (Result<UserModel>) -> Void) {
    SandboxService.createsandboxUser()
        // 第一步:拿到userModel后,调用初始化接口,返回包含userModel和initModel的元组Promise
        .then { userModel -> Promise<(UserModel, InstallationModel)> in
            return SandboxService.initializeClient(publicKey: self.keyPairs.publicKey)
                .then { initModel in
                    // 用Promise.value把同步的元组包装成Promise,符合返回要求
                    return Promise.value((userModel, initModel))
                }
        }
        // 第二步:接收(userModel, initModel)元组,调用设备服务接口,返回包含三者的元组Promise
        .then { (userModel, initModel) -> Promise<(UserModel, InstallationModel, DeviceServerResponseModel)> in
            return SandboxService.deviceServerServiceCaller(
                authKey: initModel.token.token,
                apiKey: userModel.apiKey,
                privaKey: self.keyPairs.privateKey
            )
            .then { serverResponseModel in
                return Promise.value((userModel, initModel, serverResponseModel))
            }
        }
        // 第三步:接收所有上下文数据,调用会话服务接口
        .then { (userModel, initModel, serverResponseModel) -> Promise<UserModel> in
            return SandboxService.sessionServiceCaller(
                authKey: initModel.token.token,
                apiKey: userModel.apiKey,
                privaKey: self.keyPairs.privateKey
            )
        }
        .done { userModel in
            completionHandler(Result.success(userModel))
        }
        .catch { error in
            completionHandler(Result.error(error))
        }
}

关键说明:

  • 用元组打包上下文:每个then块完成后,把当前步骤的结果和之前需要保留的数据(比如userModel、initModel)打包成元组,这样后续的then块就能直接获取所有需要的数据。
  • Promise.value()的合理性:因为then块要求返回Promise类型,而元组是同步的非Promise值,用Promise.value()把它包装成已完成的Promise是完全符合Promise规范的操作,这不是“不合理方案”,反而是链式调用中传递同步上下文的标准方式。
  • 移除实例变量依赖:这样代码更纯粹,避免了实例变量带来的状态污染问题,尤其是在并发调用该方法时,不会出现多个请求互相覆盖self.userModel的情况。

如果某些步骤不需要保留所有之前的数据,你可以调整元组的内容,只保留后续步骤需要的字段,让代码更简洁。

内容的提问来源于stack exchange,提问作者Emre Önder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:32:46