应用retryWhen到一个抛出错误的自定义观察者,无法正常工作

时间:2018-01-17 23:50:10

标签: node.js mongodb rxjs reactivex

我正在使用此自定义class以反应方式连接到MongoDB:

function RxMongodb(driver){
    driver == null ? this.driver = require('mongodb').MongoClient : this.driver = driver.MongoClient;
}

RxMongodb.prototype.connect = function(uri){
    return Rx.Observable.create((observer)=>{
        if (dbInstance != null){
            console.log('already connected, repassing db instance');
            observer.next(dbInstance);
        } else {
            console.log('connecting for the first time');
            this.driver.connect(uri, (err, db)=>{
                if (err) {
                    console.log('rx mongo error! ' + err);
                    observer.error(err);
                } else {
                    dbInstance = db;
                    observer.next(dbInstance);
                    observer.complete();
                }
            });
        }
    });
}

有时我的mongodb需要时间加载(它与此代码一起调用),所以我想等一下再试一次。我正在使用retryWhen来执行此操作:

Rx.Observable.fromEvent(emitter, 'go').
flatMap(()=>rx_mongo.connect(mongo_parameters.url)).                   
retryWhen(errors=>errors.delay(2000)).take(10).
... 

此处rx_mongoRxMongbdb的实例。我可以在控制台中看到发生错误,因此它调用observer.error(err),但它不会重试任何内容。

另外,我看到很多文档使用onNext,onError,onCompleted intead of next,error,completed。哪一个是现代的?这是我的,对吗?

更新

我认为这可能与error()有关。调用error()和抛出错误有什么区别?

1 个答案:

答案 0 :(得分:2)

您正在将 retryWhen 设置在错误的位置...您必须将它放在mongo connect observable上。虽然,mongo connect Observable必须很热,并且每次事件发生时都不会被激活。发射。只有当retryWhen + 10个意图完成时才需要再次触发。你也没有很好地设置take(10),你不需要重试9次以执行10次连接意图。

我编辑了我的帖子并添加了一个示例。 mousedown 事件会模拟您的go事件。查看share()运算符,重要的是,对于我执行的更多点击,源observable将在不再触发连接时共享。



//emit value every 1s
const source = Rx.Observable.fromEvent(document, 'mousedown');
const hotMongoConnect$ = Rx.Observable.interval(1000) 
                                 .map(val => {throw val;}) // mocks rxMongo.connect
                                 .retryWhen((errors)=> {
                                     return errors
                                      .scan(function(errorCount, err) {
                                        if(errorCount >= 9) {
                                          throw errorCount + 1;
                                        }
                                        return errorCount + 1;
                                       }, 0)
                                       .do(errorCount => console.log('connect failed. retry nº: ', errorCount))
                                       .delayWhen(val => Rx.Observable.timer(2000));
                                    })
                                    .share();

const example = source.flatMap(() => hotMongoConnect$)
const subscribe = example.subscribe(val => console.log(val), error => console.error('Error connectiong to server, nº of intents:', error));

<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.8/dist/global/Rx.umd.js"></script>
&#13;
&#13;
&#13;

希望这有帮助。