使用RxJS同步异步操作

时间:2017-02-13 22:32:09

标签: rxjs5

我想了解更多RxJS概念。这是我目前正在努力解决的问题。我想抽象使用异步调用访问数据库,我希望同步访问。

我可以有一系列行动,
  - 对数据执行异步调用   - 我希望下一步行动延迟到上一个行动完成为止   - 操作的调用者应获得异步操作结果的Observable。

示例:

类的用户调用Action1:读取DB项,计算下一个状态(例如增量字段),写入DB
然后..
类的用户调用下一个操作(Action2),但Action1仍在进行中 Action2:读取DB(在Action1:write完成之前不应该启动)

如何使用RxJS + Typescript完成?

/////////////////////////////////

同时我有这段代码:

import * as Rx from 'rxjs';

var actionQueue = new Rx.Subject< () => Rx.Observable<any>>();
actionQueue
  .concatMap( v => v() )
  .subscribe( v => {});

// example action with result type number
function action1 ( v : number ) : Rx.Observable<number> {
  console.log( ':: action1: ', v );
  var res = new Rx.Subject<number>();
  actionQueue.next( () => {
    console.log( '>> action1: ', v );
    setTimeout( ()=>{
      console.log( '<< action1: ', v );
      res.next(v);
      res.complete();
    }, 500 );
    return res;
  });
  return res;
}

// some actions enqueue now, after 700+2500ms
action1( 11 ).subscribe( v => console.log( 'XX action1: ', v ));
action1( 22 ).subscribe( v => console.log( 'XX action1: ', v ));
action1( 33 ).subscribe( v => console.log( 'XX action1: ', v ));

setTimeout( ()=>{
  action1( 44 ).subscribe( v => console.log( 'XX action1: ', v ));
}, 700 );

setTimeout( ()=>{
  action1( 55 ).subscribe( v => console.log( 'XX action1: ', v ));
}, 2500 );

输出显示它执行连续的操作 作为打字稿/ js noob ...这段代码有陷阱吗?有更优雅的方式吗?

1 个答案:

答案 0 :(得分:0)

如何使用delayWhen()运算符?

// Observable wrapping action1.
const obsAction1 = Observable.create(observer => {
  // Read DB item
  // Calculate next state
  // Write to DB
  // Then:
  observer.complete();
});

// Private observable wrapping action2.
// DO NOT subscribe to it directly.
const _obsAction2 = Observable.create(observer => {
  // Read DB
  // Then:
  observer.complete();
});

// Public observable wrapping action2 AND delayed by action 1.
// This is what the client code should subscribe to.
const obsAction2 = _obsAction2.delayWhen(obsAction1);

现在代码消耗了observables:

obsAction1.subscribe(val => console.log(val));

// Values will be received only when `obsAction1` emits or completes.
obsAction2.subscribe(val => console.log(val));