当使用具有异步操作的RefluxJS商店时,您可以轻松地在您的操作之间设置竞争条件。
例如,我们的商店处于状态X.异步操作A从X调用,在完成之前,还会从X调用另一个异步操作B.从此处,无论哪个操作首先完成,它都会错。
期望的行为是:
A B
X -> Y -> Z
其中B不是基于X,而是基于Y,并且导致一致的Z状态,而不是基于相同状态的两个动作,导致状态不一致:
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应用程序中是可能的)解决方案?或者,我们是否应该首先以某种方式避免这些情况?
答案 0 :(得分:0)
你的例子似乎更像是一个关于&#34;真理来源&#34;的概念的问题。比什么都重要。您只在客户端存储数字的当前状态,但只有在收到服务器端对其进行的操作的确认后才更新它。
当然,这会产生问题。你以一种奇怪的方式将数字和数字存储的动作混合起来,在任何特定时刻,数字都不是单一的真实来源。在行动被宣告结束的时间之间处于不确定状态......这是不合适的。
要么存储号码客户端,并且每次添加它,直接添加到该号码然后告诉服务器端新号码是什么...(即客户端承担责任作为事实的来源对于客户端运行时的数字)
或者存储号码服务器端,每次通过客户端的操作启动它时,服务器都会返回新的更新号码。 (即数字的真实来源完全是服务器端)。
然后,即使出现种族问题,您仍然可以获得该数字的真实来源,并且可以检查和确认该来源。例如,如果服务器端拥有该数字的真实来源,那么API也可以在每次返回时返回该值的状态的时间戳,并且您可以根据从API获得的最后一个值来检查它。确保您使用最新值。