Rxjs 包括确认的可观测模式

Rxjs 包括确认的可观测模式,rxjs,observable,Rxjs,Observable,我正在做一件事,记录来自队列的数据。将队列处理成一个可观察的队列非常简单,这样我就可以在代码中有多个端点接收队列中的信息 此外,我可以确定信息是按顺序到达的。这一点也可以很好地工作,因为观测值确保了这一点但是,一个棘手的问题是,我不希望观察者在完成前一件事情的处理之前收到下一件事情的通知。但是观察者所做的处理是异步的 作为一个更具体的例子,这个例子可能足够简单。假设我的队列包含URL。我在我的代码中将它们公开为可见的。我订阅了一个观测者,其工作是获取URL并将内容写入磁盘(这是一个人为的示例,所

我正在做一件事,记录来自队列的数据。将队列处理成一个可观察的队列非常简单,这样我就可以在代码中有多个端点接收队列中的信息

此外,我可以确定信息是按顺序到达的。这一点也可以很好地工作,因为观测值确保了这一点但是,一个棘手的问题是,我不希望观察者在完成前一件事情的处理之前收到下一件事情的通知。但是观察者所做的处理是异步的

作为一个更具体的例子,这个例子可能足够简单。假设我的队列包含URL。我在我的代码中将它们公开为可见的。我订阅了一个观测者,其工作是获取URL并将内容写入磁盘(这是一个人为的示例,所以不要对这些细节提出异议)。重要的一点是,获取和保存是异步的。我的问题是,在观察者完成之前,我不希望他们从观察者那里得到“下一个”URL

但是在Observer界面上对
next
的调用返回
void
。因此,观察者无法与实际完成异步任务的我进行通信


有什么建议吗?我怀疑可能有某种操作符可以被编码,基本上会保留未来的值(在内存中排队?),直到它知道观察者已经准备好了。但我希望按照某种既定模式已经存在类似的东西。

我以前遇到过类似的用例

window.document.onkeydown=(e)=>{
返回错误
}
让计数=0;
让asyncTask=(名称、时间)=>{
时间=时间| | 2000
返回接收、可观察、创建(功能(obs){
setTimeout(函数(){
计数++
obs.next('任务:'+名称+计数);
日志('Task:',count',time',Task complete')
obs.complete();
},时间);
});
}
let subject=new Rx.subject()
让queueExec$=new Rx.Subject()
Rx.Observable.fromEvent(btnA,'点击').订阅(()=>{
queueExec$.next(异步任务('A',4000))
})
Rx.Observable.fromEvent(btnB,'click')。订阅(()=>{
queueExec$.next(异步任务('B',4000))
})
Rx.Observable.fromEvent(btnC,'click')。订阅(()=>{
queueExec$.next(异步任务('C',4000))
})
queueExec$.concatMap(值=>value)
.订阅(功能(数据){
console.log('onNext',data);
}, 
函数(错误){
console.log('onError',错误);
},函数(){
console.log('completed')

});你所描述的听起来像是“背压”。您可以在RXJS4文档中了解它。然而,这里提到的是RxJS 5中不存在的运算符。例如,看一看“受控可观察对象”,它应该是指您所需要的

我认为您可以通过
concatMap
和主题实例实现同样的效果:

const asyncOperationEnd = new Subject();

source.concatMap(val => asyncOperationEnd
    .mapTo(void 0)
    .startWith(val)
    .take(2) // that's `val` and the `void 0` that ends this inner Observable
  )
  .filter(Boolean) // Always ignore `void 0`
  .subscribe(val => {
    // do some async operation...
    // call `asyncOperationEnd.next()` and let `concatMap` process another value
  });
在您的描述中,您提到的“观察者”实际上像Subject一样工作,因此创建一个定制的Subject类可能更有意义,您可以在任何可观察的链中使用它。

这不就是吗


如果您想同时允许多个抓取,请使用with concurrency参数。

因此,如果我理解这一点,您的
asyncTask
将返回一个可观察的值,而不是一个值。该可观察对象只发布一个值,然后关闭。但是,当您运行
concatMap
将它们连接在一起时,其效果是,在第一个观测值完成之前,您无法从下一个观测值中获取值(异步完成时就是这样)。这是一个有趣的想法。我发现了一些更适合我的情况,但是对于其他用例来说,这绝对是一个有趣的想法。用这种模式你可以在Asic CQuy上扔任何东西,只要它是可观察到的。在某些情况下,它更灵活
// Requests are coming in a stream, with small intervals or without any.
const requests=Rx.Observable.of(2,1,16,8,16)
    .concatMap(v=>Rx.Observable.timer(1000).mapTo(v));

// Fetch, it takes some time.
function fetch(query){
  return Rx.Observable.timer(100*query)
      .mapTo('!'+query).startWith('?'+query);
}

requests.concatMap(q=>fetch(q));