【问题标题】:Design pattern for working with Ajax data. What is the right way?用于处理 Ajax 数据的设计模式。什么是正确的方法?
【发布时间】:2017-02-27 11:15:57
【问题描述】:

我正在开发一个反应应用程序,我在其中大量使用从 AJAX 请求中获得的数据。假设我可以在myserver.com/people.json 检索数据,其中的数据如下所示:

var peopleList = [ 
    {id:0, name: "John Smith", age: 30},
    {id:1, name: "Jane Green", age: 19},
    {id:2, name: "Bob Dylan", age: 69},
    ...
]

people 的列表最终可能在 10,000 到 100,000 之间,我永远不会显示完整的列表,而是通过 id 标识一些子列表和单个实例。

我的问题不在于显示或查询大型顺序数据集,因此分页可能无关紧要。以我需要显示的一些数据为例:

var group = { name: "Woodworking", people_set: [12, 4, 678, 90] }

/* Should come out like:

WOODWORKING
- Peter Johnson
- Anna Holland
- David Green
- Erica Davis
*/

这篇文章已经过编辑,以更好地反映可用选项和作者的推理

我看到四种五种可能的方法来解决这个问题:

1.每次需要显示实例时进行单独的 AJAX 调用

因此,请致电 myserver.com/people/<id>.json 以仅检索所需的数据。我担心这可能会用大量小请求将服务器蜂拥而至,并且需要将大量异步代码混入我的代码中。

2。每次进行一次完整的 AJAX 调用并迭代数组

在初始化时进行调用,数据作为数组保存在内存中(见上文)。每次需要一个实例时,我都会迭代数组,直到找到与 .id 匹配值的对象。

3.和以前一样,但是从对象中查找

我将 Array 转换为一个对象,其中字符串化的键与要查找的 id 匹配。这可能会更快?

{ "0": { name: "John Smith", age: 30},
  "1": { name: "Jane Green", age: 19},
  "2": { name: "Bob Dylan", age: 69},
  ...
}

4.我相信列表索引与 id 匹配

由于我控制数据库,我永远不会删除记录并将ids 维护为从 0 开始的顺序列表。查找可以很简单:

peopleList[id]

这似乎仍然是一种高风险的方法,因为无意中删除了主键会导致应用程序无法正常运行。

5.创建一个额外的 indexArray 以快速找到索引

在创建 peopleList 后,创建一个包含 id 的附加数组:[0, 1, 4, ...]。在 indexArray 上使用indexOf() 快速找到索引,并使用该索引从 peopleList 中检索记录。

// This would be the way to lookup a name
peopleList[indexArray.indexOf(<id>)].name

讨论与选择

看起来14 方法只是糟糕的设计。对于查找,方法235 慢两个数量级(!),因此如果您大量使用查找,则应避免使用。虽然3 仍然稍快一些,但我决定选择5,因为保留数组看起来更优雅。

This post 寻址选项234,并对查找进行基准比较。

【问题讨论】:

  • 最好对它进行分页/偏移。只请求 50-100 人的块,如果需要,加载更多块。
  • 我更新了问题以说明为什么分页不是恕我直言的答案。

标签: javascript ajax reactjs object design-patterns


【解决方案1】:

进行一次完整的 AJAX 调用并每次迭代数组这是正确的选择,如果我是你,我会将我的数据存储在 redux 状态树中。

但是,这取决于您存储状态数据的位置。每次您在使用该 Ajax 调用结果的组件挂载时进行 Ajax 调用时,您都必须将该数据存储在某处的状态中。所以你有两个选择,a) 你可以将数据存储在本地组件状态中,这将持续到该组件卸载,并且你必须在组件重新安装时再次加载它,或者 b) 你可以使用 Redux 存储来管理你的状态数据,这将保持它的持久性。

【讨论】:

  • 现在还没有准备好深入研究 Redux,因为 React 几乎是我现在所能咀嚼的。是否有更快的方法来迭代数组,因为您可以期望它相对于id 是有序且密集的?如果您知道 id 非常接近结尾,那么简单地从 0 开始迭代似乎很幼稚......
【解决方案2】:

我会将响应保留为一个数组,因为它具有有用的方法,例如 map、filter 和 reduce,您可以使用这些方法来呈现您的 jsx。

如果你可以从你的服务器做一个 jsonp 响应,它只会发送一个选择的值,那可能是最好的。它避免了可能下载 10 000 行以仅呈现 100 行,但一次获取 100 行(或许多行)不应导致服务器过载。它可能类似于前端的fetch('/someApi?take=100&amp;from=0')

或者,如果您一次性获得整个列表,您可以使用array.slice(beginning, end) 获取您想要的部分并呈现它。

render() {
     const shownUsers = this.state.users.slice(this.state.from, this.state.from + 100);
     return (<ul>
       {shownUsers.map(user => {
         const username = user && user.name
         return <li>{username}</li>
       }
     </ul>
   }

如果您将数据保存为数组并且您当前的 id 系统,则 id“应该”与数组索引相同。当/如果从数据库中删除一行时,这可能会帮助您克服错误。数组方法可以优雅地处理空索引,只需记住防御性地查找数据。 const name = user &amp;&amp; user.name 将避免 cannot find 'name' of undefined 错误。

【讨论】:

    【解决方案3】:

    能够通过进一步研究找到令人满意的方法并更新问题以反映这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多