PromiseKit可选承诺

时间:2017-04-19 14:28:21

标签: swift xcode promisekit

我目前正在调查是否应将PromiseKit集成到现有项目中。

我的主要问题是我需要实现一个最多可以调用5个Web服务的业务逻辑。根据之前的结果调用其中一些。

我目前的架构基于使用相互调用的闭包来分解多个函数中的代码。

我试图找出是否可以使用PromiseKit(或其他任何东西)编写更易于管理的代码。

以下是我需要做的一些伪代码:

        // if true, the phone validation is skipped
        let forceRequest = false
        // true if a 3rd party web-service has checked the phone number
        let isVerified = true
        // true if the 3rd party checked the phone number and it is valid
        var isValid = false

        if !isVerified {
            // update value from 3rd party web-service
            isValid = isValidPhoneNumberPromise()
        }

        // If the phone no is invalid stop execution (unless forced)
        if !isValid && !force {
            throw MyError.error1
        }

        // web request to create order
        createOrderPromise()

        // if we have a valid phone number, first send an SMS, then update log
        if isValid {
            sendSmsPromise()
            updateLogPromise()
        }

根据totiG的回答,我提出了以下变体:

var isValid = isValid

        firstly
        {
            return Controller.verify(isVerified: isVerified, isValid: isValid)
        }
        .then { _isValid -> Promise<Int> in
            isValid = _isValid
            return Controller.createOrder()
        }
        .then
        { _ -> Promise<Bool> in
            if isValid {
                return Controller.isSendSms()
            }

            return Promise (value: true)
        }
        .then
        { _ -> Promise<Bool> in
            if isValid {
                return Controller.updateLog()
            }

            return Promise (value: true)
        }
        .catch
        { error in
            print (error)
        }

1 个答案:

答案 0 :(得分:2)

是的,你可以使用PromiseKit来做到这一点。我写了一个基本的例子来展示你可能需要的东西。请记住,当步骤失败时会抛出错误并在catch块中处理这些失败。在我的示例中,验证步骤通过,但是如果调用了isValidPhoneNumber,它将阻止其他步骤运行。在我放置Promise(值:)的地方,您会将实际的Web服务调用。如果始终需要运行更新日志的最后一步,则可以将其放在.always

enum Errors: Error {
    case invalidPhone
    case orderFailed
}

func orderPromise() {
    firstly {
        self.verify(isVerified: false, force: true)
    }.then { _ in
        self.createOrder()
    }.then { orderNumber in
        self.sendSms(orderNumber: orderNumber)
    }.then { smsSent in
        self.updateLog(smsSent: smsSent)
    }.catch { error in
        //Do something with the error
    }
}

private func verify(isVerified: Bool, force: Bool) -> Promise<Bool> {
    if isVerified || force {
        return Promise(value: true)
    }
    return isValidPhoneNumber()
}

private func isValidPhoneNumber() -> Promise<Bool> {
    return Promise(error: Errors.invalidPhone) //Assume that this fails, then catch in 'orderPromise' will be run
}

private func createOrder() -> Promise<String> {
    //Assume an order number is being passed back to use in the message
    return Promise(value: "Order100")
}

private func sendSms(orderNumber: String) -> Promise<Bool> {
    return Promise(value: true)
}

private func updateLog(smsSent: Bool) -> Promise<Bool> {
    return Promise(value: true)
}