RxJS使用超时

时间:2018-04-12 11:36:37

标签: javascript node.js rxjs rxjs5

我想使RxJS可观察,这将同时产生异步请求和超时。
-> promise -> filter -> promise and timeout -> complete
在具有async / await代码的同步版本中,代码如下所示:

(async () => {
  const gameInfo = await function1(); // return undefined or {start, id}

   if (!gameInfo) {
     return;
   }

  const gameStart = gameInfo.start;

  setTimeout(() => {
     function3(gameInfo._id).then(res => {
         console.log('Done');
     });
  }, getDelayTime(gameStart));

 await function2();

 // Completed
})();

const getDelayTime = (time) => {
  const now = new Date();
  const parsedTime = new Date(time);

  console.log('In delay', parsedTime.getTime() - now.getTime());
  return parsedTime.getTime() - now.getTime();
};

所以目标是从function1()异步接收一些数据,然后对它的第一部分进行一些操作,同时启动计时器,在时间结束时进行第二次操作,无论是{{1}结束与否。


所以,在RxJS中我带来了类似的东西:

function3()

但是,我的目标没有按预期工作。

如果我将代码更改为以下内容:

Rx.Observable
  .fromPromise(function1())
  .filter(data => data)
  .concatMap(data => {
    Rx.Observable.fromPromise(function2());
    Rx.operators.delay(data => Rx.operators.timeout(getDelayTime(data.start)));
  })
  .subscribe(
    data => {
       console.log('Data', data); 
       function3(data._id)
    }
    err => console.error('Err', err.message),
    () => console.log('Completed'),
  );

它不起作用。
所以,我的问题是,如何在RxJS中创建并发计时器和异步http请求

1 个答案:

答案 0 :(得分:1)

延迟通话的一种方法是执行timer后跟*map(flatMap,switchMap,...)运算符。它将等待持续时间,然后订阅您放在*map中的任何内容。

您可以使用combineLatestwithLatestFrom和类似订阅多个可观察对象。但通常人们想对结果做些什么。

如果您不关心结果,您可以随时使用tap运算符来触发副作用。或者您可以在订阅中的onNext回调中执行此操作。

我认为这可以做你想要的,但说实话,这是一个奇怪的用法。如果你可以分享更多关于你想要实现的目标,我们可能会提供更好的建议。

function test(id, timeout) {
  console.log('called', id);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('resolved', id);
      resolve();
    }, timeout);
  });
}

Rx.Observable.fromPromise(test(1, 1000))
  .flatMap(() => Rx.Observable.combineLatest(
    Rx.Observable.fromPromise(test(2, 3000)),
    Rx.Observable.timer(1234).flatMap(() => 
      Rx.Observable.fromPromise(test(3, 100)))
  ))
  .subscribe(() => { console.log('onNext'); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.9/Rx.min.js"></script>