我想了解对主题的“下一次”调用之后的代码执行顺序。
背景:我有3个类(将它们称为HaveSubject,HaveSubscription1,HaveSubscription2)。 HaveSubject需要通过预订了HS1和HS2的Subject来告诉HS1和HS2做某事。必须先完成其任务,然后HaveSubject才能继续执行somethingVeryImportant方法。
伪代码:
class HaveSubject {
// Angular service
public mySubject$: Subject<string> = new Subject<string>();
public codeImExecuting() {
this.mySubject$.next('input for tasks')
this.somethingVeryImportant();
}
private somethingVeryImportant() {
// stuff
}
}
class HaveSubscription1 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
});
}
}
class HaveSubscription2 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
});
}
}
我的问题是:在继续执行somethingVeryImportant方法之前,确保HS1和HS2已执行附加到其订阅的代码的最佳方法是什么?如果操作顺序是:HaveSubject在主题上调用“ next”-> HS1和HS2执行任务-> HaveSubject继续执行下一行代码,这很重要,那么我没有问题。我只是不确定在订阅中收到订阅中的“下一个”项目后立即执行订阅。
注意:有一些我通常无法做的事情,例如将HaveSubject注入到另外两个中,因为其他两个是动态创建的(即,我可能没有,没有一个或两个HaveSubscriptionX ,不清楚会创建多少,而这些是组件提供的Angular服务,而不是根目录...)。
有想法吗?
答案 0 :(得分:0)
在HaveSubscription#
中完成边工作时最简单的呼叫事件(不理想的是大量重复的运行检查第二个选项)
class HaveSubject {
// Angular service
public mySubject$: Subject<string> = new Subject<string>();
public mySubjectDone$: Subject<void> = new Subject<void>();
public constructor() {
this.mySubjectDone$.subscribe(this.somethingVeryImportant.bind(this));
}
public codeImExecuting() {
this.mySubject$.next('input for tasks')
}
private somethingVeryImportant() {
// stuff
}
}
class HaveSubscription1 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
hs.mySubjectDone$.next()
});
}
}
class HaveSubscription2 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
hs.mySubjectDone$.next()
});
}
}
或者如果您不想从HaveSubscription#
进行任何操作,则会触发延迟操作
class HaveSubject {
// Angular service
public mySubject$: Subject<string> = new Subject<string>();
public constructor() {
this.mySubject$.pipe(
debounceTime(16) // delay or auditTime, debounceTime, ...
).subscribe(this.somethingVeryImportant.bind(this));
}
public codeImExecuting() {
this.mySubject$.next('input for tasks')
}
private somethingVeryImportant() {
// stuff
}
}
class HaveSubscription1 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
});
}
}
class HaveSubscription2 {
// Angular service
constructor(private hs: HaveSubject) {
this.hs.mySubject$.subscribe(inputStr => {
// did I do this before somethingVeryImportant is called?
});
}
}
如果您有某种版本控制机制可以对HaveSubscription#
中所做的更改做出反应,则可以执行以下操作:
this.mySubject$.pipe(
map(this.calculateVersion),
distinctUntilChanged(),
).subscribe(this.somethingVeryImportant.bind(this));
答案 1 :(得分:0)
因此,由于流程如此,您似乎已经做出了一些可疑的体系结构决定
这要求主题对象了解其观察者,这与rxjs哲学的相反。理想的解决方案是解决这些体系结构问题。很难说出如何做到这一点,而又不了解事情的发生方式或原因,总体目标是什么。
但是,您可以以一种非常可靠的方式完成此操作,您需要在第一个函数上添加一些主题,以表明相关服务已完成:
// BAD
this.strike = function() {
this.health -= this.damage
console.log(this.health)
if(this.aggro === true) { setTimeout(this.strike(), this.ratio); } //<== This line crashes your comp because it's just recursing in to 'strike' calls
}
// OK
this.strike = function() {
this.health -= this.damage
console.log(this.health)
if(this.aggro === true) { setTimeout(this.strike.bind(this), this.ratio); } //<= we make sure 'this' will ref the right object here, and pass the REFERENCE of the method to setTimeout, not the RESULT of a call
}
// Also OK maybe?
this.strike = function() {
this.health -= this.damage
console.log(this.health)
if(this.aggro === true) { setTimeout(this.strike, this.ratio); }
}.bind(this)
,并让mySubject $的观察者完成后调用imDone()。