Open zhouzhongyuan opened 6 years ago
[Differences between ReduceStore
and Store
]()
Using ` is useless in FLux
Container`. Why?
Flux Utils are not a feature-complete framework that will handle all use cases. Why?
store
?There is one sentence in constructor of FluxStore
this._dispatchToken = dispatcher.register((payload) => {
this.__invokeOnDispatch(payload);
});
invoke:
__invokeOnDispatch(payload: Object): void {
this.__changed = false;
this.__onDispatch(payload);
if (this.__changed) {
this.__emitter.emit(this.__changeEvent);
}
}
invoke:
this.setState(
(prevState, currentProps) => getState(
prevState,
currentProps,
context,
),
);
* this setState
was added by this._fluxContainerSubscriptions.addListener
in FluxContainer
invoke:
Component update
...
Container.create
do?Dispatcher
?类似,但不是。
Dispatcher is used to broadcast payloads to registered callbacks. This is different from generic pub-sub systems in two ways: 1) Callbacks are not subscribed to particular events. Every payload is dispatched to every registered callback.(多对多) 2) Callbacks can be deferred in whole or part until other callbacks have been executed.(可以异步)
Dispatcher.register(cb)
中cb
要求是同步函数吗?
根据这个An async version of Facebook's flux dispatcher, 推断,要求是同步函数。
Dispatcher
唯一的依赖Use invariant() to assert state which your program assumes to be true. Provide sprintf-style format (only %s is supported) and arguments to provide information about what broke and what you were expecting. The invariant message will be stripped in production, but the invariant will remain to ensure logic does not differ in production.
一言以蔽之:更好的输出错误信息
A way to provide descriptive errors in development but generic errors in production.
Dispatcher
的原理 register(callback) {
var id = _prefix + _lastID++;
this._callbacks[id] = callback;
return id;
}
/**
* Dispatches a payload to all registered callbacks.
*
* @param {object} payload
*/
dispatch(payload) {
invariant(
!this._isDispatching,
'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.'
);
this._startDispatching(payload);
try {
for (var id in this._callbacks) {
if (this._isPending[id]) {
continue;
}
this._invokeCallback(id);
}
} finally {
this._stopDispatching();
}
}
/**
* Set up bookkeeping needed when dispatching.
*
* @param {object} payload
* @internal
*/
_startDispatching(payload) {
for (var id in this._callbacks) {
this._isPending[id] = false;
this._isHandled[id] = false;
}
this._pendingPayload = payload;
this._isDispatching = true;
}
/**
* Call the calback stored with the given id. Also do some internal
* bookkeeping.
*
* @param {string} id
* @internal
*/
_invokeCallback(id) {
this._isPending[id] = true;
this._callbacks[id](this._pendingPayload);
this._isHandled[id] = true;
}
/**
* Clear bookkeeping used for dispatching.
*
* @internal
*/
_stopDispatching() {
this._pendingPayload = null;
this._isDispatching = false;
}
waitFor
的原理 /**
* Waits for the callbacks specified to be invoked before continuing execution
* of the current callback. This method should only be used by a callback in
* response to a dispatched payload.
*
* @param {array<string>} ids
*/
waitFor(ids) {
invariant(
this._isDispatching,
'Dispatcher.waitFor(...): Must be invoked while dispatching.'
);
for (var ii = 0; ii < ids.length; ii++) {
var id = ids[ii];
if (this._isPending[id]) {
invariant(
this._isHandled[id],
'Dispatcher.waitFor(...): Circular dependency detected while ' +
'waiting for `%s`.',
id
);
continue;
}
invariant(
this._callbacks[id],
'Dispatcher.waitFor(...): `%s` does not map to a registered callback.',
id
);
this._invokeCallback(id);
}
}