iOS RxSwift как «вытащить» из Observable.of (1,2,3)?

Я работаю над проблемой RX swift, чтобы имитировать 4 нажатия пользователя. Требуется, чтобы они происходили асинхронно в ответ на другие события в RX. Поэтому я не могу использовать таймеры или интервалы.

Я думаю о функции, которая будет «вытягивать» из наблюдаемого, который может выдавать до 4 значений, а затем завершать работу. У меня вопрос:

Какой оператор позволяет мне «тянуть» или проходить через все элементы наблюдаемой от начала до конца?

func recursive(duration: int) -> Observable<Int>
{
// logic that may terminate recursion based on network conditions

//logic to terminate if number of taps exceeded
If I take from the taps array observable, and it completes - terminate recursion
}

Идея состоит в том, чтобы попытаться создать «чистую» реализацию RX, не полагаясь на внешние переменные. Я думаю о Zip, но изо всех сил пытаюсь понять, как это связано с рекурсивным характером решения.


person Alex Stone    schedule 13.08.2018    source источник
comment
Можете ли вы нарисовать мраморную диаграмму входов и выходов? Затем мы можем понять логику функции.   -  person Daniel T.    schedule 14.08.2018


Ответы (1)


Если я понимаю, что вы хотите, я сделал что-то подобное с помощью обещаний несколько лет назад. Может быть, это могло бы тебе помочь. https://gist.github.com/dtartaglia/2b19e59beaf480535596

Ниже я обновил код обещания, чтобы использовать Singles:

/**
Repeatedly evaluates a promise producer until a value satisfies the predicate.
`promiseWhile` produces a promise with the supplied `producer` and then waits
for it to resolve. If the resolved value satisfies the predicate then the
returned promise will fulfill. Otherwise, it will produce a new promise. The
method continues to do this until the predicate is satisfied or an error occurs.

- Returns: A promise that is guaranteed to fulfill with a value that satisfies
the predicate, or reject.
*/

func doWhile<T>(pred: @escaping (T) -> Bool, body: @escaping () -> Single<T>, fail: (() -> Single<Void>)? = nil) -> Single<T> {
    return Single.create { event in
        func loop() {
            _ = body().subscribe(onSuccess: { (t) -> Void in
                if !pred(t) {
                    event(SingleEvent.success(t))
                }
                else {
                    if let fail = fail {
                        _ = fail().subscribe(onSuccess: { loop() }, onError: { event(SingleEvent.error($0)) })
                    }
                    else {
                        loop()
                    }
                }
            }, onError: {
                event(SingleEvent.error($0))
            })
        }
        loop()
        return Disposables.create()
    }
}

Я не ожидаю, что вы сможете просто использовать вышесказанное, но, надеюсь, вы сможете почерпнуть из этого вдохновение.

person Daniel T.    schedule 13.08.2018
comment
Это очень похоже на то, как мы пытаемся реализовать петли с задержкой по времени в RX. - person Alex Stone; 14.08.2018
comment
Похоже на оператор sample. - person Daniel T.; 14.08.2018