如何产生 Mobx.autorun 以防止在 class 构造函数中触发?
How to yield Mobx.autorun to prevent firing in class constructor?
在这个 class 中,我使用初始化的 bool 状态来产生 Mobx.autorun 执行。否则 'this' 未完全分配并导致错误。有 another/cleaner 的方法吗?
class GameMaster{
private _initialized:boolean = false;
private _store:IDomainStore;
private _moveDisposer:Lambda;
/**
*
* @param store - client or server store
*/
constructor(store:IDomainStore){
this._store = store;
console.log(this._store);
//todo abstract services to decouple client device from GameMaster because it is also used on the server.
this._moveDisposer = autorun(()=>{
// prevent firing in the constructor
if(this._initialized) {
this.present(
<IIntent>{
fromId: 'GeoLocation.service',
toIds: [Meteor.userId()],
wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
});
}
});
this._initialized = true;
}
public present(intent:IIntent):boolean{
...
}
...
}
这是我在另一个文件中观察到的:
@observable coordinates = {
lng:0,
lat:0
};
我认为这是解决问题的好方法,但是初始化字段也应该是可观察的。否则更改 _initialized
不会导致自动 运行 重新 运行。
但在那种情况下,我不确定初始化变量在您中究竟实现了什么,因为您在 auto运行 之后的第一条语句是将 initialized 设置为 true?
所以我不完全确定你要实现什么:将 auto运行 / present
调用推迟到构造函数的末尾,或者跳过第一个 present
打电话?
更新答案
如果你想防止副作用(在这种情况下发送 present
),有一个简单的模式。线索是确保您计算出副作用所需的任何值,但不要自己触发副作用。所以在你的例子中,这看起来
constructor(store:IDomainStore){
let firstRun = true;
this._moveDisposer = autorun(()=>{
// make sure all information is tracked
const presenceInfo = <IIntent>{
fromId: 'GeoLocation.service',
toIds: [Meteor.userId()],
wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
}
// but prevent the side effect in the first run
if(!firstRun) {
this.present(presenceInfo);
} else {
firstRun = false;
}
});
}
(请注意,将来可能不再需要该标志,因为现有 proposal 可以将参数 firstRun
传递给 auto运行ned 函数)。
在这个 class 中,我使用初始化的 bool 状态来产生 Mobx.autorun 执行。否则 'this' 未完全分配并导致错误。有 another/cleaner 的方法吗?
class GameMaster{
private _initialized:boolean = false;
private _store:IDomainStore;
private _moveDisposer:Lambda;
/**
*
* @param store - client or server store
*/
constructor(store:IDomainStore){
this._store = store;
console.log(this._store);
//todo abstract services to decouple client device from GameMaster because it is also used on the server.
this._moveDisposer = autorun(()=>{
// prevent firing in the constructor
if(this._initialized) {
this.present(
<IIntent>{
fromId: 'GeoLocation.service',
toIds: [Meteor.userId()],
wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
});
}
});
this._initialized = true;
}
public present(intent:IIntent):boolean{
...
}
...
}
这是我在另一个文件中观察到的:
@observable coordinates = {
lng:0,
lat:0
};
我认为这是解决问题的好方法,但是初始化字段也应该是可观察的。否则更改 _initialized
不会导致自动 运行 重新 运行。
但在那种情况下,我不确定初始化变量在您中究竟实现了什么,因为您在 auto运行 之后的第一条语句是将 initialized 设置为 true?
所以我不完全确定你要实现什么:将 auto运行 / present
调用推迟到构造函数的末尾,或者跳过第一个 present
打电话?
更新答案
如果你想防止副作用(在这种情况下发送 present
),有一个简单的模式。线索是确保您计算出副作用所需的任何值,但不要自己触发副作用。所以在你的例子中,这看起来
constructor(store:IDomainStore){
let firstRun = true;
this._moveDisposer = autorun(()=>{
// make sure all information is tracked
const presenceInfo = <IIntent>{
fromId: 'GeoLocation.service',
toIds: [Meteor.userId()],
wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
}
// but prevent the side effect in the first run
if(!firstRun) {
this.present(presenceInfo);
} else {
firstRun = false;
}
});
}
(请注意,将来可能不再需要该标志,因为现有 proposal 可以将参数 firstRun
传递给 auto运行ned 函数)。