我使用RxJS的方式如下,得到了意想不到的值顺序.下面的代码可以在Stackblitz中执行.
编辑-简化代码.我们可以简化为两个简单的观察者,对相同的行为主体以不同的顺序接收数据.
this.state$ = new BehaviorSubject<any>({ a: null, b: null });
const obs1 = this.state$
.subscribe((value) => {
console.log('obs 1', value);
if (value.a == 1) this.state$.next({ a: 2, b: 3 });
});
const obs2 = this.state$.subscribe((value) => console.log('obs 2', value));
this.state$.next({ a: 1, b: 1 });
以下是日志(log)的外观
obs 1 {a: null, b: null}
obs 2 {a: null, b: null}
obs 1 {a: 1, b: 1}
obs 1 {a: 2, b: 3}
obs 2 {a: 2, b: 3}
obs 2 {a: 1, b: 1}
我希望相同行为对象的观察者以相同的顺序接收emits 的值,无论这些值来自哪里.
以前的代码
class sampleState {
a: any;
b: any;
}
const initialState: sampleState = {
a: null,
b: null,
};
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: ``,
})
export class App {
name = 'Angular';
protected _state$: BehaviorSubject<sampleState>;
state$: Observable<sampleState>;
constructor() {
this._state$ = new BehaviorSubject<sampleState>(initialState);
this.state$ = this._state$.asObservable();
this.select((state) => state.a).subscribe((value) => {
console.log('a ' + value);
if (value == 1) this.setState({ b: 3 });
});
this.select((state) => state.b).subscribe((value) => {
console.log('b ' + value);
});
this._state$.subscribe((value) => console.log(value));
this.setState({ a: 1, b: 1 });
}
public get state() {
return this._state$.getValue();
}
public setState(newState: any) {
this._state$.next({
...this.state,
...newState,
});
}
public select<K>(mapFn: (state: sampleState) => K): Observable<K> {
return this._state$.asObservable().pipe(
map((state: sampleState) => mapFn(state)),
distinctUntilChanged()
);
}
}
我得到了以下日志(log)
{a: null, b: null}
{a: 1, b: 3}
{a: 1, b: 1}
虽然我期待着
{a: null, b: null} // initialisation
{a: 1, b: 1} // setState
{a: 1, b: 3} // if a == 1 => set b = 3
在调用下一个setState之前,第一个setState似乎没有完成.有没有一种方法可以改变这种行为,使状态按顺序改变?