当使用带有异步操作的RefluxJS存储时,您可以很容易地在操作之间产生竞争条件。
对这个问题的抽象描述
例如,我们的存储处于状态X。从X调用异步操作A,在它完成之前,调用另一个异步操作B,也从X调用。从这里开始,无论哪个操作首先完成,它都会出错。
想要的行为应该有:
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的方式是错误的,而这种情况并不发生在一个结构合理的应用程序中。
正在排队进行异步操作(假设这在反流应用程序中是可能的)解决方案?或者我们应该从某种程度上避免这些场景?
发布于 2017-03-23 21:08:25
你的例子似乎更像是“真相之源”的概念,而不是任何其他的问题。您只存储数字客户端的当前状态,但只在收到服务器端对其执行的操作的确认后才更新它。
当然会有问题的。你把数字上的动作和数字的存储以一种奇怪的方式混合在一起,在这种情况下,在任何给定的时刻,对数字都没有单一的真实来源。在这个动作被称为finished...and的那段时间之间,它处于一个模糊的状态,这是不好的。
要么存储数字客户端,每次添加到它时,直接添加该号码,然后告诉服务器端新号码是什么.(即当客户端运行时,客户端承担责任作为数字的真相来源)
或者存储数字服务器端,每次使用来自客户端的操作时,服务器都会返回新的更新编号。(也就是说,数字的真相来源完全是服务器端的)。
然后,即使出现种族问题,你仍然有一个关于数字的真相来源,并且这个来源可以被检查和确认。例如,如果服务器端持有数字的真相源,则API还可以在每次返回该值时返回该值状态的时间戳,并且可以对照从API获得的最后一个值来检查它,以确保实际使用的是最新值。
https://stackoverflow.com/questions/36940449
复制相似问题