Javascript RxJS:为什么内部可观测的发射是第一位的?

Javascript RxJS:为什么内部可观测的发射是第一位的?,javascript,rxjs,Javascript,Rxjs,我使用的是RxJS 6,我有以下几点: 我们希望为指定的bufferTime缓冲元素,但是如果在比bufferTime更长的时间内没有任何事情发生,我们希望第一个元素立即触发 顺序: [------bufferTime------] Input over time: [1, 2, 3, -------------|---4, 5, 6 ----------------] Output over time: [1]-----------------[2,3]---[4]-----------

我使用的是RxJS 6,我有以下几点:

我们希望为指定的bufferTime缓冲元素,但是如果在比bufferTime更长的时间内没有任何事情发生,我们希望第一个元素立即触发

顺序:

[------bufferTime------]

Input over time:
[1, 2, 3, -------------|---4, 5, 6 ----------------]


Output over time:
[1]-----------------[2,3]---[4]------------------[5,6]
这是让我达到目的的代码:

source$.pipe buffersource$.pipe throttleTimebufferTime,asyncScheduler,{leading:true,trailing:true},
delay10/问题在于,当新值出现时,观察者订阅流的顺序保持不变:订阅的第一个将首先接收值,然后是下一个值,依此类推

在中,buffer将首先订阅内部流,内部流将首先订阅source$,然后buffer将在第二位订阅source$。澄清一下,当一个新值进入时,第一个接收到新值的将是内部可观察对象,因为它在buffer之前订阅了源

在这种情况下,它被替换掉了,因此它应该可以在没有任何额外工作的情况下工作

作为v6的更干净的解决方案,有一个操作员可以帮助您:subscribeOn。通过此选项,您可以指定订阅操作员时要使用的计划程序,在您的情况下,通过将微任务与asapScheduler一起使用,它应该可以工作:

source$.pipe buffersource$.pipe 订阅计划程序, throttleTimebufferTime,asyncScheduler,{leading:true,trailing:true}, 这样,对源的内部订阅将在缓冲区订阅后延迟


请注意,如果使用此实现创建自定义运算符,可能需要使用重载publishmulticasted$=>…,对源$进行多播。。。,否则,此代码段将对source$进行两次订阅,可能会发送两次请求?

问题在于,当出现新值时,观察者订阅流的顺序将保持不变:订阅的第一个将首先接收该值,然后是下一个值,依此类推

在中,buffer将首先订阅内部流,内部流将首先订阅source$,然后buffer将在第二位订阅source$。澄清一下,当一个新值进入时,第一个接收到新值的将是内部可观察对象,因为它在buffer之前订阅了源

在这种情况下,它被替换掉了,因此它应该可以在没有任何额外工作的情况下工作

作为v6的更干净的解决方案,有一个操作员可以帮助您:subscribeOn。通过此选项,您可以指定订阅操作员时要使用的计划程序,在您的情况下,通过将微任务与asapScheduler一起使用,它应该可以工作:

source$.pipe buffersource$.pipe 订阅计划程序, throttleTimebufferTime,asyncScheduler,{leading:true,trailing:true}, 这样,对源的内部订阅将在缓冲区订阅后延迟


请注意,如果使用此实现创建自定义运算符,可能需要使用重载publishmulticasted$=>…,对源$进行多播,否则此代码段将对源$进行两次订阅,可能会发送两次请求?

请尝试以下代码,您可以在中使用它:

输出为:

[a0]2020-09-21T14:39:49.895Z

[a1,a2,a3]2020-09-21T14:39:50.899Z

[a4]2020-09-21T14:39:51.096Z


[a5,a6,a7]2020-09-21T14:40:30.967Z

尝试以下代码,您可以在

输出为:

[a0]2020-09-21T14:39:49.895Z

[a1,a2,a3]2020-09-21T14:39:50.899Z

[a4]2020-09-21T14:39:51.096Z


[a5,a6,a7]2020-09-21T14:40:30.967Z

为什么要使用throttleTime来缓冲元素?因为throttleTime内置了前导和尾随选项,这正是我想要的行为。如果我只使用bufferTime,我不会从第一项(即前导元素)获得即时响应。我愿意接受其他解决问题的方法,比如为什么要使用throttleTime来缓冲元素?因为throttleTime内置了前导和尾随选项,这正是我想要的行为。如果我只使用bufferTime,我不会从第一项(即前导元素)获得即时响应。我愿意接受其他解决问题的方法,谢谢你的不同方法!谢谢你的不同方法!在更少的代码和更多的信息方面,这比我的答案要好,这对我来说甚至是有趣的,谢谢。谢谢你如此透彻地解释它,这正是我所需要的。谢谢你提供了相关源代码的链接!在更少的代码和更多的信息方面,这比我的答案要好,这对我来说甚至是有趣的,谢谢。谢谢你如此透彻地解释它,这正是我所需要的。谢谢你提供了相关源代码的链接!
[------bufferTime------]

Input over time:
[1, 2, 3, -------------|---4, 5, 6 ----------------]


Output over time:
[]------------------[1,2,3]--[]------------------[4,5,6]
const source$: Observable<string> = interval(300).pipe(
  map(x => "a" + x),
  share()
);

source$.pipe(
  exhaustMap(value => {
    return concat(
      of([value]),
      source$.pipe(
        bufferTime(1000),
        take(1)
      )
    );
  })
).subscribe(x => console.log(x, new Date()));