Recursion 避免使用RxJS5可观测值进行递归

Recursion 避免使用RxJS5可观测值进行递归,recursion,rxjs,observable,rxjs5,Recursion,Rxjs,Observable,Rxjs5,好的,我想避免使用可观察的递归,使用外部和内部事件的组合,而不是调用相同的方法/函数 现在我有这个: Queue.prototype.deq = function (opts) { opts = opts || {}; const noOfLines = opts.noOfLines || opts.count || 1; const isConnect = opts.isConnect !== false; let $dequeue = this.init

好的,我想避免使用可观察的递归,使用外部和内部事件的组合,而不是调用相同的方法/函数

现在我有这个:

Queue.prototype.deq = function (opts) {

    opts = opts || {};

    const noOfLines = opts.noOfLines || opts.count || 1;
    const isConnect = opts.isConnect !== false;

    let $dequeue = this.init()
        .flatMap(() => {
            return acquireLock(this)
                .flatMap(obj => {
                    if(obj.error){

                    // if there is an error acquiring the lock we
                    // retry after 100 ms, which means using recursion
                    // because we call "this.deq()" again

                        return Rx.Observable.timer(100)
                            .flatMap(() => this.deq(opts));
                    }
                    else{
                        return makeGenericObservable()
                          .map(() => obj);
                    }
                })

        })
        .flatMap(obj => {
            return removeOneLine(this)
                .map(l => ({l: l, id: obj.id}))
        })
        .flatMap(obj => {
            return releaseLock(this, obj.id)
                .map(() => obj.l)
        })
        .catch(e => {
            console.error(e.stack || e);
            return releaseLock(this);
        });

    if (isConnect) {
        $dequeue = $dequeue.publish();
        $dequeue.connect();
    }

    return $dequeue;

};
与上面使用递归(希望是正确的)的方法不同,我想使用一种更具事件性的方法。如果acquireLock函数返回了一个错误,我想每100毫秒重试一次,一旦成功,我想停止,我不知道怎么做,我很难测试它……这是正确的吗

Queue.prototype.deq = function (opts) {

    // ....

    let $dequeue = this.init()
        .flatMap(() => {
            return acquireLock(this)
                .flatMap(obj => {
                    if(obj.error){
                        return Rx.Observable.interval(100)
                            .takeUntil(
                                acquireLock(this)
                                .filter(obj => !obj.error)
                            )
                    }
                    else{

                        // this is just an "empty" observable
                        // which immediately fires onNext()

                        return makeGenericObservable()
                              .map(() => obj);
                    }
                })

        })

     // ...

    return $dequeue;

};
有没有办法让它更简洁?我也只想重试5次左右。我的主要问题是-如何在间隔旁边创建计数,以便每100毫秒重试一次,直到获得锁或计数达到5为止

我需要这样的东西:

.takeUntil(this or that)
也许我可以简单地将takeUntils链接起来,如下所示:

                   return Rx.Observable.interval(100)
                    .takeUntil(
                        acquireLock(this)
                        .filter(obj => !obj.error)
                    )
                    .takeUntil(++count < 5);
但可能是在找一些不那么麻烦的东西

但是我不知道在哪里存储/跟踪
count
变量

还希望使其更加简洁,并可能检查其正确性


我必须说,如果这个东西有效,它就是非常强大的编码结构。

有两个操作符可以帮助您:和。这两个服务器都在源服务器上重新订阅,因此重试失败的操作

检查此示例,其中我们有一个在首次
count
订阅时失败的可观察对象:

让getObs=(计数)=>{
返回Rx.Observable.create((subs)=>{
log('Subscription count=',count);
如果(计数){
计数--;
子错误(“错误”);
}否则{
下一步(“成功”);
subs.complete();
}
return()=>{};
});
};
getObs(2).subscribe(console.log,console.log);
getObs(2).重试(2).订阅(console.log,console.log);
getObs(3).重试(2).订阅(console.log,console.log)
                return Rx.Observable.interval(100)
                    .takeUntil(
                        acquireLock(this)
                        .filter(obj => !obj.error)
                    )
                    .takeUntil( Rx.Observable.timer(500));