从消费者方面取消,可能会使用takeUntil进行调用,但这不一定非常动态。但是,在这种情况下,我希望从等式的生产者方面取消Observable,就像你希望在promise链中取消Promise一样(使用本机实用程序这是不可能的)。
假设我从一个方法返回了这个Observable。 (此Queue库是一个读/写文本文件的简单持久队列,我们需要锁定读/写,以免被破坏)。
Queue.prototype.readUnique = function () {
var ret = null;
var lockAcquired = false;
return this.obsEnqueue
.flatMap(() => acquireLock(this))
.flatMap(() => {
lockAcquired = true;
return removeOneLine(this)
})
.flatMap(val => {
ret = val; // this is not very good
return releaseLock(this);
})
.map(() => {
return JSON.parse(ret);
})
.catch(e => {
if (lockAcquired) {
return releaseLock(this);
}
else {
return genericObservable();
}
});
};
我有两个不同的问题 -
如果我无法获取锁定,我怎样才能“取消”observable,只返回一个没有结果的空Observable?我是否真的必须在每个返回调用中执行if / else逻辑来确定当前链是否被取消,如果是,则返回一个空的Observable?通过为空,我的意思是一个Observable,简单地触发onNext / onComplete,没有任何错误的可能性,也没有onNext的任何值。从技术上讲,我认为这不是一个空的Observable,所以我正在寻找那些真正被称为它的东西。
如果你看一下这个特殊的代码序列:
.flatMap(() => acquireLock(this))
.flatMap(() => {
lockAcquired = true;
return removeOneLine(this)
})
.flatMap(val => {
ret = val;
return releaseLock(this);
})
.map(() => {
return JSON.parse(ret);
})
我正在做的是在方法的顶部存储对ret的引用,然后在稍后再次引用它。我正在寻找的是一种将从removeOneLine()触发的值传递给JSON.parse()的方法,而不必在链外设置一些状态(这简直不优雅)。
答案 0 :(得分:3)
1)这取决于你的方法acquireLock
如何工作 - 但我假设如果它无法获取锁定会抛出错误,在这种情况下你可以创建你的流catch
并将后备流设置为空流:
return Rx.Observable.catch(
removeLine$,
Rx.Observable.empty()
);
2)为了节省有状态的外部变量,你可以简单地链接一个mapTo
:
let removeLine$ = acquireLock(this)
.flatMap(() => this.obsEnqueue
.flatMap(() => removeOneLine(this))
.flatMap(val => releaseLock(this).mapTo(val))
.map(val => JSON.parse(val))
.catch(() => releaseLock(this))
);
答案 1 :(得分:2)
根据你对cancel的定义,它是为了防止一个observable向下游发送一个值。要防止observable推送值,可以使用filter:
可以这么简单:
observable.filter(_ => lockAcquired)
如果lockAcquired
为真,则只会向下游发送通知。