jjzjj

javascript - 套接字在Flux单向数据流中的适合位置是什么?

coder 2025-02-17 原文

套接字在Flux单向数据流中的适合位置是什么?我已经阅读了两种关于远程数据应进入Flux单向数据流的思路。我看到的是获取Flux应用程序的远程数据的方式是在进行服务器端调用时,例如,在一个 promise 中,然后将其解决或拒绝。在此过程中可能会触发三种可能的操作:

  • 乐观更新 View (FooActions.BAR)
  • 的初始操作
  • 解决异步 promise 时的成功操作(FooActions.BAR_SUCCESS)
  • 异步 promise 被拒绝时的错误操作(FooActions.BAR_ERROR)

  • 商店将监听 Action 并更新必要的数据。我已经看到了 Action 创建者和商店内部发出的服务器端调用。我将 Action 创建者用于上述过程,但是不确定通过Web套接字获取数据是否应进行类似处理。我想知道 socket 在下面的图表中的位置。

    最佳答案

    在将Flux与WebSocket或普通的旧HTTP请求/轮询一起使用时,实际上没有任何区别。您的商店负责在应用程序状态更改时发出更改事件,并且如果该更改来自UI交互,WebSocket或发出HTTP请求,则不应从商店外部看到该事件。这实际上是Flux的主要优点之一,因为无论在何处更改应用程序状态,它都会通过相同的代码路径。

    一些Flux实现倾向于使用 Action / Action 创建者来获取数据,但是我并不完全同意。

    操作是发生的事情,它们会修改您的应用程序状态。诸如“用户更改了一些文本并点击保存”或“用户删除了项目”之类的东西。可以将操作想像成数据库的事务日志。如果您丢失了数据库,但是保存并序列化了所有曾经发生的操作,则可以仅重播所有这些操作并最终获得与丢失的状态/数据库相同的状态。

    因此,诸如“给我ID为X的项目”和“给我所有项目”之类的不是行动,而是问题,是关于该应用程序状态的问题。在我看来,应该是商店通过您在这些商店中公开的方法来回答这些问题。

    使用 Action / Action 创建者进行获取是很诱人的,因为获取需要异步。通过将异步内容包装在操作中,您的组件和存储可以完全同步。但是,如果这样做,则会模糊 Action 的定义,并迫使您假设您可以将整个应用程序状态放入内存(因为只有在内存中有答案的情况下,您才可以同步响应)。

    因此,这就是我如何看待助焊剂和不同概念的方法。

    存储

    这显然是您的应用程序状态所在的地方。商店封装并管理状态,并且是该状态发生突变的唯一位置。当状态改变时,它也是发出事件的地方。

    商店还负责与后端进行通信。当状态更改并且需要与服务器同步时,存储与后端进行通信,并且在需要内存中没有的数据时,也与服务器进行通信。它具有get(id)search(parameters)等方法。这些方法用于您的问题,即使状态可以放入内存中,它们也都返回promise。这很重要,因为您可能会遇到用例,该用例的状态不再适合内存,或者无法在内存中进行过滤或进行高级搜索。通过从问题方法返回 promise ,您可以在从内存返回或询问后端之间进行切换,而不必在商店外进行任何更改。

    操作

    我的 Action 非常轻巧,他们对持久化封装的突变一无所知。它们只是承载从组件到商店的变异的意图。对于较大的应用程序,它们可以包含一些逻辑,但不能包含服务器通信之类的东西。

    组件

    这些是您的React组件。他们通过在商店上调用问题方法并呈现这些方法的返回值来与商店进行交互。他们还订阅商店公开的change事件。我喜欢使用高阶组件,这些组件只是包装另一个组件并将 Prop 传递给它。一个例子是:

    var TodoItemsComponent = React.createClass({
      getInitialState: function () {
        return {
          todoItems: null
        }
      },
      componentDidMount: function () {
        var self = this;
        TodoStore.getAll().then(function (todoItems) {
          self.setState({todoItems: todoItems});
        });
    
        TodoStore.onChange(function (todoItems) {
          self.setState({todoItems: todoItems});
        });
      },
      render: function () {
        if (this.state.todoItems) {
          return <TodoListComponent todoItems={this.state.todoItems} />;
        } else {
          return <Spinner />;
        }
      }
    });
    
    var TodoListComponent = React.createClass({
      createNewTodo: function () {
        TodoActions.createNew({
          text: 'A new todo!'
        });
      },
      render: function () {
        return (
          <ul>
            {this.props.todoItems.map(function (todo) {
              return <li>{todo.text}</li>;
            })}
          </ul>
          <button onClick={this.createNewTodo}>Create new todo</button>
        );
      }
    });
    

    在此示例中,TodoItemsComponent是更高阶的组件,它包装了与商店进行通信的细节。提取待办事项后,它会渲染TodoListComponent,并在此之前渲染一个微调框。由于它会将待办事项作为TodoListComponent的 Prop 传递,因此该组件仅需专注于渲染,并且只要商店中发生任何更改,它都将被重新渲染。渲染组件保持完全同步。另一个好处是TodoItemsComponent只专注于获取数据并将其传递,从而使其可用于需要待办事项的任何渲染组件。

    高阶组件

    术语“高阶组件”来自术语“高阶函数”。高阶函数是返回其他函数的函数。因此,高阶组件是只包装另一个组件并返回其输出的组件。

    关于javascript - 套接字在Flux单向数据流中的适合位置是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30474083/

    有关javascript - 套接字在Flux单向数据流中的适合位置是什么?的更多相关文章

    1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    3. ruby - 其他文件中的 Rake 任务 - 2

      我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

    4. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

      作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

    5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

      Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

    6. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

      我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

    7. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

      我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

    8. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

      我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

    10. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

      为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

    随机推荐