代码之家  ›  专栏  ›  技术社区  ›  quirimmo

当按顺序执行操作时,Rxjs与concat操作符一起出现问题

  •  3
  • quirimmo  · 技术社区  · 6 年前

    我使用的是rxjs6,我正在执行两个异步操作,其中顺序很重要。

    我确实有这么一段代码可以完美地工作:

    dbmsProxy.createDatastores().subscribe(() => {
        UsersDAO.insert(users).subscribe(() => {
            console.log('FINISHED ALL THE CHAIN');
        });
    });
    

    concat 属于 rxjs

    concat([dbmsProxy.createDatastores(), UsersDAO.insert(users)]).subscribe();
    

    在DBMSProxy方法下面

    public createDatastores(): Observable<string> {
        const _this: DBMSProxy = this;
        const subject = new Subject<string>();
        const subscription: Subscription = UsersDAO.createDatastore().subscribe(
            onSuccess,
            onError,
            onFinally
        );
        return subject;
    
        function onSuccess(datastore: Nedb): void {
            console.log(`USERS Datastore Created Successfully`);
            _this.db.users = datastore;
            subject.next('success');
        }
    
        function onError(err: string) {
            subject.error('error');
            console.error(err);
        }
    
        function onFinally() {
            subject.complete();
            subscription.unsubscribe();
        }
    }
    
    public insertDocuments(documents: any, datastore: Nedb): Subject<any> {
        const subject = new Subject<any>();
        datastore.insert(documents, onInsert);
        return subject;
    
        function onInsert(err: Error, newDocuments: any) {
            if (err) {
                subject.error(err);
            } else {
                // add to the documents to insert the id just created from nedb when inserting the document
                documents.forEach((document: any, ind: number) => {
                    document.id = newDocuments[ind]._id;
                });
                subject.next(documents);
            }
            subject.complete();
        }
    }
    

    在UsersDAO方法下面:

    public static createDatastore(): Subject<Nedb | string> {
            const subject = new Subject<Nedb | string>();
            const datastore = new Nedb({
                filename: USERS_DATASTORE_FULL_NAME,
                autoload: true,
                onload
            });
            return subject;
    
            function onload(err: Error) {
                if (err) {
                    subject.error(
                        `Error creating USERS datastore: ${err.name} - ${err.message}`
                    );
                } else {
                    subject.next(datastore);
                }
                subject.complete();
            }
        }
    
        public static insert(users: User[]): Observable<any> {
            return DBMSProxy.getInstance()
                .insertDocuments(users, DBMSProxy.getInstance().db.users)
                .pipe(catchError((val: any) => of('Error inserting the users')));
        }
    

    你知道怎么回事吗?

    1 回复  |  直到 6 年前
        1
  •  4
  •   quirimmo    6 年前

    我目前的解决方案是将 Subject Observable ,用第二个创建一个新的Observable,并去掉方括号(否则我将返回Observable而不是结果),这似乎是可行的:

    const operations = concat(
        dbmsProxy.createDatastores().asObservable(),
        defer(() => UsersDAO.insert(users))
    );
    operations.subscribe(onSubscribe);
    function onSubscribe(result: any) {
        console.log('Finished all: ', result);
    }