如何在Observable运行时共享它,在非Observable时重新订阅

时间:2018-08-20 12:26:52

标签: rxjs rxjs6

我有一个Observable,当我订阅它时,我想要:

  • 如果正在执行,则返回当前执行的结果
  • 如果不是,请重新/执行Observable。

例如:

我有一个wait函数。此函数等待1秒钟,然后返回当前的time()

function wait(): Observable<number> {
  return new Observable<number>((observer) => {
    setTimeout(() => {
      observer.next((new Date).getTime());
      observer.complete();
    }, 1000);
  });
}

现在,我有一个代码,每0.4秒调用此wait函数。

  • 第一次致电wait(0.4秒)将等待1秒钟并返回当前时间
  • 由于执行了wait,因此第二次调用wait(0.8秒)将返回第一点的可观测值和相同结果
  • 由于没有执行,对wait的第三次调用(1.2秒)将再次等待1秒

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解您的示例,我认为第3个呼叫应获得初始时间戳,第4个呼叫应获得新的时间戳。

无论如何,您可以这样半共享Observable来做到这一点:

const timeStream = timer(1000)
    .pipe(map(() => (new Date).getTime()), share(), take(1));

function wait(): Observable<number> {
    return timeStream;
}

setTimeout(() => wait().subscribe(console.log), 400);
setTimeout(() => wait().subscribe(console.log), 800);
setTimeout(() => wait().subscribe(console.log), 1200);
setTimeout(() => wait().subscribe(console.log), 1600);

https://stackblitz.com/edit/typescript-wiqpbf

关键是share()和take(1)组合-本质上,这将使Observable仅在“运行”时共享。


OP的最终解决方案:

import {Observable} from 'rxjs';
import {share, take} from 'rxjs/operators';

function myFunction(): Observable<number> {
  return new Observable<number>((observer) => {
    setTimeout(() => {
      observer.next((new Date).getTime());
      observer.complete();
    }, 1000);
  });
}

const task$ = myFunction().pipe(share(), take(1));

setInterval(() => {
  task$.subscribe(console.log);
}, 400);