首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在回流中排队异步操作

在回流中排队异步操作
EN

Stack Overflow用户
提问于 2016-04-29 14:05:59
回答 1查看 129关注 0票数 4

当使用带有异步操作的RefluxJS存储时,您可以很容易地在操作之间产生竞争条件。

对这个问题的抽象描述

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

  1. B首先用状态Y1结束,A最后结束,然后用Y2覆盖状态Y1。
  2. A首先用状态Y2完成,B用Y1覆盖Y2。

想要的行为应该有:

代码语言:javascript
复制
  A    B
X -> Y -> Z

其中,B不是基于X,而是基于Y,并导致一致的Z状态,而不是基于同一状态的两个操作,从而导致不一致状态:

代码语言:javascript
复制
  A   
X -> Y1   .--> Y2
  \      /  
   '----'
     B

已执行的问题示例

我写了一个最小的工作示例,用Node运行,说明了我正在讨论的问题。

代码语言:javascript
复制
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中使用这些依赖项

代码语言:javascript
复制
{
  "dependencies": {
    "q": "^1.3.0",
    "reflux": "^0.3",
    "reflux-promise": "^1"
  }
}

问题的性质

我期望RefluxJS排队操作,但它没有,所以我正在寻找一种方法来正确地排序这些操作。但是,即使我设法以某种方式排队(所以B是在A之后发布的),我如何确定,当A完成时,发出B仍然是一个有效的操作?也许我一开始使用RefluxJS的方式是错误的,而这种情况并不发生在一个结构合理的应用程序中。

正在排队进行异步操作(假设这在反流应用程序中是可能的)解决方案?或者我们应该从某种程度上避免这些场景?

EN

回答 1

Stack Overflow用户

发布于 2017-03-23 21:08:25

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

当然会有问题的。你把数字上的动作和数字的存储以一种奇怪的方式混合在一起,在这种情况下,在任何给定的时刻,对数字都没有单一的真实来源。在这个动作被称为finished...and的那段时间之间,它处于一个模糊的状态,这是不好的。

要么存储数字客户端,每次添加到它时,直接添加该号码,然后告诉服务器端新号码是什么.(即当客户端运行时,客户端承担责任作为数字的真相来源)

或者存储数字服务器端,每次使用来自客户端的操作时,服务器都会返回新的更新编号。(也就是说,数字的真相来源完全是服务器端的)。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36940449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档