Flux:等待特定事件

IT技术 javascript reactjs reactjs-flux flux
2021-03-26 21:45:10

我试图了解如何解决商店之间的依赖关系。问题是我有一个全面的数据树,需要从服务器获取依赖于另一个的请求链。

问题: waitFor异步请求不应该接缝。假设下一个事件链:

  1. NEED_A(看StoreA
  2. NEED_B(看StoreB)在这里StoreBAppDispatcher.waitFor([StoreA.dispatchToken])但其实我们想等GET_A
  3. SOME_OTHER_ACTION(看StoreA

第三步waitFor第二步中断,因为StoreA.dispatchToken被要求 SOME_OTHER_ACTION

问题: 等待某些特定动作的真正方法是什么 ( GET_A)?

我们来看一下代码(请注意三个PROBLEM注释):

商店A

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
  }

});

商店B

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();
  }
});
1个回答

这是来自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') );
我相信无论操作是同步还是异步,该模式都适用。该示例恰好是同步的。我也对异步操作使用相同的模式。
2021-06-02 21:45:10
您能否举一个带有两个异步回调的示例,其中一个依赖于另一个并且可能在它之前发生?
2021-06-05 21:45:10
链的想法是避免多个并发回调。如果对服务器的一次调用触发了两个操作,那么您可以在服务器上使用一个链来避免这种情况。否则,您只需要编写等待代码即可。并行编程非常复杂。你想避免这种情况。
2021-06-12 21:45:10
语法错误,我提到:*“链接两个异步请求”
2021-06-14 21:45:10
这个例子是关于链接同步动作的。是的,对服务器有一个异步请求,但只有一个。我的问题是关于链接到相互依赖的异步请求。
2021-06-19 21:45:10