【问题标题】:Flux: waitFor specific eventFlux:waitFor特定事件
【发布时间】:2015-12-08 20:20:05
【问题描述】:

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

问题: 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)?

我们看一下代码(请注意三个PROBLEMcmets):

商店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();
  }
});

【问题讨论】:

  • 我使用一系列动作而不是等待。
  • @JanakaStevens 你是什么意思?例子pleaseeeee!)

标签: javascript reactjs reactjs-flux flux


【解决方案1】:

这是来自https://github.com/calitek/ReactPatternsReact.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') );

【讨论】:

  • 这个例子是关于链接同步动作的。是的,对服务器有一个异步请求,但只有一个。我的问题是关于链接到相互依赖的异步请求。
  • 语法错误,提示:*"chaining two asynchronous requests"
  • 我相信无论动作是同步的还是异步的,该模式都适用。该示例恰好是同步的。我也对异步操作使用相同的模式。
  • 能否举个例子,其中有两个异步回调,其中一个依赖于另一个并且可能在它之前发生?
  • 链的想法是避免多个并发回调。如果对服务器的一次调用触发了两个操作,那么您将在服务器上使用一个链来避免这种情况。否则,您只需编写等待代码。并行编程非常复杂。你想避免这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多