The queue of asynchronous actions for reflux

When using RefluxJS stores with asynchronous actions, you can easily get race conditions between your actions.

Brief Description of the Problem

For example, our store is in state X. Asynchronous action A is called from X and before its completion, another asynchronous action B is also called from X. From here, no matter what action ends first, it goes wrong.

  • B ends first with state Y1, A ends last and overwrites state Y1 with Y2.
  • A first ends with state Y2, B overwrites Y2 with Y1.

Desired behavior:

  A    B
X -> Y -> Z

Where B is not based on X, but on Y and leads to a consistent state of Z instead of two actions based on the same state, which leads to an inconsistent state:

  A   
X -> Y1   .--> Y2
  \      /  
   '----'
     B

, Node, , .

var Q = require('q');
var Reflux = require('reflux');
var RefluxPromise = require('reflux-promise');
Reflux.use(RefluxPromise(Q.Promise));

var AsyncActions = Reflux.createActions({
    'add': { asyncResult: true }
});

var AsyncStore = Reflux.createStore({
    init: function () {
        // The state
        this.counter = 0;

        AsyncActions.add.listenAndPromise(this.onAdd, this);
    },

    // Increment counter after a delay
    onAdd: function(n, delay) {
        var that = this;
        return apiAdd(this.counter, n, delay)
        .then(function (newCounter) {
            that.counter = newCounter;
            that.trigger(that.counter);
        });
    }
});

// Simulate an API call, that makes the add computation. The delay
// parameter is used for testing.
// @return {Promise<Number>}
function apiAdd(counter, n, delay) {
    var result = Q.defer();

    setTimeout(function () {
        result.resolve(counter + n);
    }, delay);

    return result.promise;
}

// Log the store triggers
AsyncStore.listen(console.log.bind(undefined, 'Triggered'));

// Add 3 after 1 seconds.
AsyncActions.add(3, 1000);
// Add 100 almost immediately
AsyncActions.add(100, 1);

// Console output:
// > Triggered 100
// > Triggered 3

// Desired output (queued actions):
// > Triggered 3
// > Triggered 103

package.json

{
  "dependencies": {
    "q": "^1.3.0",
    "reflux": "^0.3",
    "reflux-promise": "^1"
  }
}

, RefluxJS , . . - ( B A), , A , B - ? , RefluxJS, .

( , Reflux) ? ?

+4
1

" ", - . , .

, . , , . , ... .

, , , , , ... (.. , )

, , , . (.. ).

, , , , . , , API , , , API, , .

0

All Articles