我试图了解如何解决商店之间的依赖关系。问题是我有一个全面的数据树,需要从服务器获取一个相互依赖的请求链。
问题: waitFor
接缝不应该用于异步请求。假设下一个事件链:
StoreA
)StoreB
)此处StoreB
执行AppDispatcher.waitFor([StoreA.dispatchToken])
。但实际上我们想要等待GET_A
StoreA
)自waitFor
调用StoreA.dispatchToken
以来的第二步,第三步中断了SOME_OTHER_ACTION
。
问题: 等待某些特定操作(GET_A
)的真实方式是什么?
让我们来看看代码(请注意三条PROBLEM
条评论):
StoreA
var a = [];
var StoreA = assign({}, EventEmitter.prototype, {
getAProps: () => copyOfAProps(a);
asyncGetA: () => ... //Async request returns Promise
});
StoreA.dispatchToken = AppDispatcher.register((action) => {
switch(action.type) {
NEED_A:
StoreA.asyncGetA().then((data) => {
ActionCreator.getA(data); //Dispatches GET_A event
});
break;
GET_A:
a = action.data;
StoreA.emitChange();
SOME_OTHER_ACTION:
//do whatever
}
});
StoreB
var b = [];
var StoreB = assign({}, EventEmitter.prototype, {
// PROBLEM: this request depends on data fetched from StoreA.asyncGetA
asyncGetB: (A) => ...
});
StoreB.dispatchToken = AppDispatcher.register((action) => {
switch(action.type) {
//PROBLEM: NEED_B may happen before GET_A
NEED_B:
//PROBLEM: As I understand waitFor doesn't work here
AppDispatcher.waitFor([StoreA.dispatchToken]);
StoreB.asyncGetB(StoreA.getAProps()).then((data) => {
ActionCreator.getB(data);
});
GET_B:
b = action.data;
StoreB.emitChange();
}
});
答案 0 :(得分:3)
以下是来自https://github.com/calitek/ReactPatterns React.13 / ReFluxWebSocket的示例。 App.js触发Api.Store对ws.api.js执行的操作。 然后ws.api.js触发Api.Store作出反应的另一个动作。 这是一系列行动的例子。
这是Api.Store.js
import Reflux from 'reflux';
import Actions from './Actions';
import ApiFct from './../utils/ws.api.js';
function _apiInit() { ApiFct.init(); }
function _apiInitDone() { ApiFct.getData(); }
function _apiSetData(data) { ApiFct.setData(data); }
var ApiStoreObject = {
listenables: Actions,
apiInit: _apiInit,
apiInitDone: _apiInitDone,
apiSetData: _apiSetData
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;
这是ws.api.js
import Actions from '../flux/Actions';
module.exports = {
socket: {},
init: function() {
this.socket = new Primus();
this.socket.on('server:GotData', this.gotData);
Actions.apiInitDone();
},
getData: function() { this.socket.send('client:GetData', {}); },
gotData: function(data) { Actions.gotData(data); Actions.gotData2(data); },
setData: function(data) { this.socket.send('client:SetData', data); },
};
这是Actions.js
import Reflux from 'reflux';
var apiActions = [
'apiInit',
'apiInitDone',
'apiSetData'
]
var wsActions = [
'gotData',
'gotData2'
]
var actionArray = wsActions.concat(apiActions);
module.exports = Reflux.createActions(actionArray);
这是app.js
'use strict';
import React from 'react';
import AppCtrl from './components/app.ctrl.js';
import Actions from './flux/Actions';
import ApiStore from './flux/Api.Store';
window.React = React;
Actions.apiInit();
React.render( <AppCtrl />, document.getElementById('react') );