Asynchronous 回流中的排队异步操作

Asynchronous 回流中的排队异步操作,asynchronous,refluxjs,Asynchronous,Refluxjs,当将RefluxJS存储与异步操作一起使用时,很容易在操作之间产生竞争条件 对问题的抽象描述 例如,我们的存储处于状态X。一个异步操作A从X调用,在它完成之前,另一个异步操作B也从X调用。从这里开始,无论哪个操作先完成,它都会出错 B首先完成状态Y1,a最后完成并用Y2覆盖状态Y1 A首先以状态Y2结束,B用Y1覆盖Y2 期望的行为是: A B X -> Y -> Z 其中,B不是基于X,而是基于Y,并导致一致的Z状态,而不是基于相同状态的两个动作,导致不一致的状态:

当将RefluxJS存储与异步操作一起使用时,很容易在操作之间产生竞争条件

对问题的抽象描述 例如,我们的存储处于状态X。一个异步操作A从X调用,在它完成之前,另一个异步操作B也从X调用。从这里开始,无论哪个操作先完成,它都会出错

  • B首先完成状态Y1,a最后完成并用Y2覆盖状态Y1
  • A首先以状态Y2结束,B用Y1覆盖Y2
  • 期望的行为是:

      A    B
    X -> Y -> Z
    
    其中,B不是基于X,而是基于Y,并导致一致的Z状态,而不是基于相同状态的两个动作,导致不一致的状态:

      A   
    X -> Y1   .--> Y2
      \      /  
       '----'
         B
    
    该问题的一个实例 我写了一个关于我所讨论的问题的最小工作示例,使用Node运行

    var Q=require('Q');
    var回流=需要(“回流”);
    var RefluxPromise=要求(“reflux-promise”);
    使用(RefluxPromise(Q.Promise));
    var AsyncActions=reflow.createActions({
    'add':{asyncResult:true}
    });
    var AsyncStore=reflow.createStore({
    init:函数(){
    //国家
    这个计数器=0;
    AsyncActions.add.ListendPromise(this.onAdd,this);
    },
    //延迟后的增量计数器
    onAdd:函数(n,延迟){
    var=这个;
    返回apiAdd(this.counter,n,delay)
    .then(函数(新计数器){
    that.counter=newCounter;
    那个.触发器(那个.计数器);
    });
    }
    });
    //模拟一个API调用,该调用进行add计算。延迟
    //参数用于测试。
    //@return{Promise}
    函数apiAdd(计数器,n,延迟){
    var result=Q.defer();
    setTimeout(函数(){
    结果.解析(计数器+n);
    },延误);
    回报结果。承诺;
    }
    //记录存储触发器
    listen(console.log.bind(未定义,'Triggered');
    //1秒后添加3。
    AsyncActions.add(31000);
    //几乎立即添加100
    AsyncActions.add(100,1);
    //控制台输出:
    //>触发100
    //>触发3
    //所需输出(排队操作):
    //>触发3
    //>触发103
    
    使用package.json中的这些依赖项

    {
    “依赖项”:{
    “q”:“^1.3.0”,
    “回流”:“^0.3”,
    “回流承诺”:“^1”
    }
    }
    
    问题的性质 我期望RefluxJS对操作进行排队,但事实并非如此。因此,我正在寻找一种方法来正确地安排这些行动。但是,即使我设法以某种方式将这些操作排队(因此在A之后发出B),我如何确定,当A完成时,发出B仍然是有效的操作? 也许我一开始就用错了RefluxJS,而这种情况在一个结构合理的应用程序中是不会发生的


    异步操作排队(假设在回流应用程序中可以)是解决方案吗?或者我们应该首先设法避免这些情况吗?

    你的例子似乎更像是一个关于“真理之源”概念的问题,而不是其他任何问题。您只存储数字客户端的当前状态,但只有在收到服务器端对其执行的操作的确认后才对其进行更新

    当然,这会造成问题。你以一种奇怪的方式将数字的行为和数字的存储混合在一起,在任何给定时刻,数字的真实性都没有单一的来源。在动作被称为“完成”的这段时间里,这是一个悬而未决的问题……这是不好的

    在客户端存储号码,每次添加时,直接添加号码,然后告诉服务器端新号码是什么。。。(即,当客户端运行时,客户端负责作为数字的真实来源)

    或者将号码存储在服务器端,每次您使用客户端的操作将其更新时,服务器都会返回新的更新号码。(即数字的真实来源完全是服务器端)

    然后,即使发生种族问题,你仍然有一个数字是什么的真相来源,这个来源可以被检查和确认。例如,如果服务器端持有数字的真实来源,那么API也可以在每次返回该值时返回该值状态的时间戳,并且您可以对照从API获得的最后一个值进行检查,以确保您实际使用的是最新的值