Как включить обработчики завершения для нескольких функций в Swift?

Рассмотрим этот код:

func test() {
    A()
    B()
    C()
    D()
    E()
}

Каждая функция здесь имеет свой собственный набор действий, таких как вызов API, их синтаксический анализ, запись результатов в файл, загрузка на серверы и т. д. и т. д.

Я хочу запускать эти функции одну за другой. Я читал об обработчиках завершения. Моя проблема с обработчиками завершения:

  • Все примеры, приведенные для понимания обработчиков завершения, имели только два метода.
  • Я не хочу помещать эти функции в какую-то другую функцию. Я хочу, чтобы все вызовы функций (от A до E) были только внутри функции Test()

Может ли кто-нибудь помочь в этом?


person Confused    schedule 07.03.2018    source источник
comment
Я хочу запускать эти функции одну за другой. Как вы думаете, почему это не так? Примечание: обработчики завершения — это код, который выполняется в конце чего-либо (как правило, какой-либо асинхронной операции).   -  person Jean-Baptiste Yunès    schedule 07.03.2018


Ответы (2)


Это легко сделать, вам просто нужно добавить аргумент закрытия для вызова по завершении. Например:

func a(completion: (() -> Void)) {
    // When all async operations are complete:
    completion()
}

func b(completion: (() -> Void)) {
    // When all async operations are complete:
    completion()
}

func c(completion: (() -> Void)) {
    // When all async operations are complete:
    completion()
}

func d(completion: (() -> Void)) {
    // When all async operations are complete:
    completion()
}

func e(completion: (() -> Void)) {
    // When all async operations are complete:
    completion()
}

func test() {
    a {
        b {
            c {
                d {
                    e {
                        // All have now completed.
                    }
                }
            }
        }
    }
}

Как видите, это выглядит ужасно. Одна проблема с несколькими асинхронными операциями, не одновременно, заключается в том, что вы в конечном итоге получаете эту ужасную вложенность.

Решения для этого существуют, я лично рекомендую PromiseKit. Он инкапсулирует блоки простыми методами цепочки, что намного чище.

person Jacob King    schedule 07.03.2018
comment
Я думаю, мы должны добавить эту строку в конец каждого метода (A-E): завершение () - person Confused; 07.03.2018

Взгляните на реактивное программирование и наблюдаемые цепочки. RxSwift станет для вас отличной библиотекой. Реактивное программирование сейчас очень популярно и было создано именно для решения таких задач, как ваша. Это позволяет вам легко создать процесс (например, сборочную линию), который преобразует входные данные в желаемые результаты. Например, ваш код в Rx будет выглядеть так:

A()
 .flatMap { resultsFromA in
    B(resultsFromA)
 }
 .flatMap { resultsFromB in
    C(resultsFromB)
 }
 .flatMap { resultsFromC in
    D(resultsFromC)
 }
 .flatMap { resultsFromD in
    E(resultsFromD)
 }
 .subscribe(onNext: { finalResult in

  //result from the process E, subscribe starts the whole 'assembly line'
  //without subscribing nothing will happen, so you can easily create observable chains and reuse them throughout your app

 })

Этот пример кода создаст процесс, в котором вы будете преобразовывать результаты исходного вызова API (A) в проанализированные результаты (B), затем записывать проанализированные результаты в файл (C) и т. д. Эти процессы могут быть синхронными или асинхронными. Реактивное программирование можно понимать как наблюдаемый паттерн на стероидах.

person FruitAddict    schedule 07.03.2018
comment
Rx — хороший способ, однако это крутая кривая обучения и требует полного изменения парадигмы. Если вы в состоянии сделать это, то во что бы то ни стало это отличная идея. К сожалению, я этого не сделал и поэтому нашел PromiseKit хорошим компромиссом. - person Jacob King; 07.03.2018
comment
Я согласен с Джейкобом Кингом, это требует смены парадигмы и некоторого времени, чтобы приспособиться. Тем не менее, отдача действительно хорошая, и в конце вы узнаете ценную вещь, которая надолго повысит вашу производительность. - person FruitAddict; 07.03.2018
comment
Как говорит FruitAdict, вы будете пожинать плоды в долгосрочной перспективе, если сможете изменить ситуацию. - person Jacob King; 07.03.2018