Как избежать ада обратного вызова на быстрых функциях, которые я не писал? - PullRequest
0 голосов
/ 09 мая 2018

Я не хочу, чтобы это было истолковано как дубликат. Я хочу иметь дело с адом обратного вызова, возникающим из-за вызовов API из Firestore (база данных Firebase, платформа Google). Я не могу изменить их объявления функций, поэтому я предполагаю, что мне придется обернуть их функции частью моего кода.

Например, в приведенном ниже коде функцию eventCreatedSuccessfully() можно вызывать только после завершения асинхронной функции. eventCreatedSuccessfully() также содержит вызов функции для firebase, у которого есть замыкание, на которое опирается другая функция и т. Д. Хотя сейчас это не вызывает у меня проблем, вероятно, это будет происходить по мере того, как мое приложение будет становиться все больше и больше. Я исследовал в Интернете и нашел решения, такие как Futures и Streams, от сторонних фреймворков, но я не знал, как интегрировать их в код, который я не могу контролировать (вызовы API).

batch.commit { (error) in
    self.dismiss(animated: true) {
        if error == nil {
            self.eventCreatedSuccessfully()
            print("Event created successfully")
        } else {
            print(error!.localizedDescription)
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Я исследовал онлайн и нашел такие решения, как Futures and Streams (...)

В большинстве случаев фьючерсы и потоки - это всего лишь структуры PromiseKit и RxSwift.

Если у вас только большое количество замыканий, попробуйте использовать PMK. Это очень просто и удобно в использовании. У PMK также есть хороший раздел документации на github.

RxSwift - более продвинутый уровень, потому что он требует от вас полного написания кода для самой парадигмы - начинается с запроса server / firebase и заканчивается пользовательским интерфейсом. Кроме того, в github PMK есть хорошая заметка о разнице этих двух.

Также следует отметить, что в Google также есть хорошая библиотека под названием promises. Согласно их тестам библиотека Google является лидером практически во всех номинациях.

0 голосов
/ 09 мая 2018

Оберните звонки в обещания. Любая из популярных библиотек сделает свое дело. На ум приходит PromiseKit, доступный (на момент написания этой статьи) по номеру https://github.com/mxcl/PromiseKit.

Вот код, который я написал для рабочего проекта (он с открытым исходным кодом), который оборачивает функцию, которая принимает завершение, и возвращает Promise, который будет сигнализировать с результатом, когда вызывается завершение. Он использует внутреннюю реализацию Promise, но этот процесс можно адаптировать к другим реализациям.

public func promise<Return>(_ task: (@escaping (Return?, Error?) -> ()) -> ()) -> Promise<Return> {
    let p = Promise<Return>()

    task { (value: Return?, error: Error?) -> Void in
        if let error = error {
            p.signal(error)
        }

        if let value = value {
            p.signal(value)
        }
    }

    return p
}

Ожидается, что завершение будет вызвано каким-либо результатом или ошибкой. Адаптируйте, как требуется для вашего варианта использования.

Ниже приведен пример использования.

public typealias BalanceCompletion = (Balance?, Error?) -> Void

func balance(completion: @escaping BalanceCompletion) {
    guard deleted == false else {
        completion(nil, KinError.accountDeleted)

        return
    }

    Stellar.balance(account: stellarAccount.publicKey!, asset: asset, node: node)
        .then { balance -> Void in
            completion(balance, nil)
        }
        .error { error in
            completion(nil, KinError.balanceQueryFailed(error))
    }
}

func balance() -> Promise<Balance> {
    return promise(balance)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...