Получить первый объект ответа в PromiseKit, а затем выполнить блок - PullRequest
3 голосов
/ 19 января 2020

Я звоню в три службы подряд. Когда я вызываю третий сервис, мне нужно использовать переменную из ответа первого сервиса, которая равна userModel. Я могу получить второй сервисный ответ, из которого initModel, но не могу достичь первой модели userModel. Мой вопрос заключается в том, как я могу использовать userModel в готовом блоке, возвращая его, а затем блокировать?

PS: Я пытался вернуть -> Promise<(UserModel,InstallationModel)> при первом вызове, но поскольку UserModel уже является объектом, а не обещанием, мне нужно преобразовать его в обещание вернуть его. Похоже, я плохой способ сделать это.

Как вы можете видеть, я храню это с self.userModel = userModel, что я не хочу делать.

func callService(completionHandler: @escaping (Result<UserModel>) -> Void) {
    SandboxService.createsandboxUser().then { userModel -> Promise<InstallationModel> in
        self.userModel = userModel
        return SandboxService.initializeClient(publicKey: self.keyPairs.publicKey)
    }.then { initModel -> Promise<DeviceServerResponseModel> in
        self.initModel = initModel
        if let unwrappedUserModel = self.userModel {
            return SandboxService.deviceServerServiceCaller(authKey: initModel.token.token,apiKey:unwrappedUserModel.apiKey,privaKey: self.keyPairs.privateKey)
        }
        throw ServiceError.handleParseError()
    }.then { serverResponseModel -> Promise<UserModel> in
        if let unwrappedInitModel = self.initModel, let unwrappedUserModel = self.userModel {
            return SandboxService.sessionServiceCaller(authKey: unwrappedInitModel.token.token, apiKey: unwrappedUserModel.apiKey, privaKey: self.keyPairs.privateKey)
        }
        throw ServiceError.handleParseError()
    }.done { userModel in
        completionHandler(Result.success(userModel))
    }.catch { error in
        completionHandler(Result.error(error))
    }
}

Ответы [ 2 ]

4 голосов
/ 06 марта 2020

Я также открыл выпуск на странице PromiseKit @Github. Здесь я также делюсь ответом Mxcl от Github.

func callService(completionHandler: @escaping (Result<UserModel>) -> Void) {
    SandboxService.createsandboxUser().then { userModel in
        firstly {
            SandboxService.initializeClient(publicKey: self.keyPairs.publicKey)
        }.then { initModel in
            SandboxService.deviceServerServiceCaller(authKey: initModel.token.token, apiKey: userModel.apiKey,privaKey: self.keyPairs.privateKey).map{ ($0, initiModel) }
        }.then { serverResponseModel, initModel in
            SandboxService.sessionServiceCaller(authKey: initModel.token.token, apiKey: userModel.apiKey, privaKey: self.keyPairs.privateKey)
        }
    }.pipe(to: completionHandler)
}
1 голос
/ 19 января 2020

Я не знаком с PromiseKit, но, поскольку это фреймворк, вы не можете реально редактировать методы таким образом, чтобы включить userModel в обратный вызов метода .done. Итак, что я хотел бы сделать, это иметь необязательное значение, объявленное в классе, где этот блок кода выполняется с типом userModel, а затем установить его на полученное значение от первого вызова, а затем установить его обратно в ноль после использования его во втором , Например:

Предположим, что типом userModel является UserModel.

final class SampleFetcher {
    let userModel: UserModel?

    func fetch() {
        SandboxService.createsandboxUser().then { userModel in
            SandboxService.initializeClient()
            // save userModel here.
            userModel = userModel
            }.done { initModel in
                // Use it here
                guard let userModel = userModel else {
                    return
                }
                SandboxService.deviceServerServiceCaller(secretID: "")
                // after you are done, set it to nil
                userModel = nil
            }.catch { error in
        }
    }
}

Если это не был фреймворк, вы могли бы написать функции таким образом, чтобы вы могли включить userModel во второй обратный вызов как хорошо.

...