我正在尝试创建一个不需要订阅的热门观察。这是一个库,我想让用户能够调用某些方法,并且无需调用subscribe()来触发可观察对象。最初我有这个:
const q = new Queue();
q.add('foo bar baz').subscribe(); // <<< need to call subscribe
Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
lines = _.flattenDeep([lines]);
var lockAcquired = false;
return this.init()
.flatMap(() => {
return acquireLock(this)
})
.flatMap(() => {
lockAcquired = true;
return appendFile(this, lines)
})
.flatMap(() => releaseLock(this))
.catch(err => {
if (lockAcquired) {
return releaseLock(this);
}
else {
return makeGenericObservable();
}
})
};
为了让观察变得热烈,我想我可以这样做:
const q = new Queue();
q.add('foo bar baz'); // <<< don't call subscribe
Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
lines = _.flattenDeep([lines]);
var lockAcquired = false;
return this.init()
.flatMap(() => {
return acquireLock(this)
})
.flatMap(() => {
lockAcquired = true;
return appendFile(this, lines)
})
.flatMap(() => releaseLock(this))
.catch(err => {
if (lockAcquired) {
return releaseLock(this);
}
else {
return makeGenericObservable();
}
})
.publish()
.share() // this too?
};
然而问题是当我调用publish()
时,没有任何反应,并且add方法似乎永远不会被完全调用(我假设序列中的第一个observable根本不会触发,因为没有调用有效订阅) 。但我虽然publish()
会自动调用可观察链?
如何从add方法 hot 返回observable?
答案 0 :(得分:2)
你误解了。 Hot observable 需要订阅,就像冷的一样。区别在于hot使用一些外部生产者(如dome元素)并开始在订阅时收听它。另一方面,cold observable在订阅时在内部创建生产者。
这导致你可以错过一些具有热观察的事件,因为外部生产者对订阅一无所知并且独立发出。在冷可观察的情况下,您不能错过任何内容,因为生产者是在订阅时创建的。
长话短说,你可以建立任何可观察的热链或冷观察链,但在你订阅之前,什么都不会发生。
PS。无需将publish
与share
一起使用,因为.publish().refCount()
后者为alias。
答案 1 :(得分:1)
如果您不想使用subscribe
,则可以手动.connect()
您的信息流或subscribe
在您的方法中:
const q = new Queue();
q.add('foo bar baz');
Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
lines = _.flattenDeep([lines]);
var lockAcquired = false;
let add$ = this.init()
.flatMap(() => {
return acquireLock(this)
})
.flatMap(() => {
lockAcquired = true;
return appendFile(this, lines)
})
.flatMap(() => releaseLock(this))
.catch(err => {
if (lockAcquired) {
return releaseLock(this);
}
else {
return makeGenericObservable();
}
})
.publish();
add$.connect();
return add$; // optional, depends if you even need the stream outside of the add-method
};
或作为使用内部subscribe
的替代方法:
const q = new Queue();
q.add('foo bar baz'); // <<< don't call subscribe
Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
lines = _.flattenDeep([lines]);
var lockAcquired = false;
let add$ = this.init()
...
.share();
add$.subscribe();
return add$;
};