【问题标题】:Simultaneous fetch() in Backbone failingBackbone 中的同时 fetch() 失败
【发布时间】:2012-06-13 23:45:29
【问题描述】:

我正在尝试实现一些看起来对 Backbone 来说应该相对微不足道的东西,但它不起作用。我正在根据用户的操作用系列填充图表。代码如下。

假设用户快速添加了两个系列。或者一条路线同时触发两个系列。常量是在第一个返回之前触发第二次获取。在这种情况下,“fetching”被记录了两次,而“fetched”只被记录了一次。这是预期的行为吗?如果不是,我应该如何构建我的代码以使其正常工作?

# Series model
class Series extends Backbone.Model
    initialize: (options) ->
        _.bindAll @
        @endpoint = state?.getEndpoint()

    url: ->
        [localApiUrl, 'metrics', @endpoint, @.get('id')].join('/')



class SeriesCollection extends Backbone.Collection
    model: Series,

    initialize: ->
        _.bindAll @
        @bind 'add', @fetched

    fetchData: ( opts ) =>
        console.log('fetching')
        @series = new Series({ id: opts.id })
        @series.fetch
            success: (model, response) =>
                @.add({
                    id: @series.get('id')
                    name: @series.get('id')
                    data : @series.get('ts')
                    marker:
                        radius: 2
                    turboThreshold: 10000 
                    dataGrouping: 
                        enabled: false
                })

    fetched: () ->
        console.log('fetched', @)

【问题讨论】:

  • 我可能是错的,但发布实际的 javascript 可能会得到更好的响应。我可能应该学习咖啡脚本,它不会那么难,但 atm 我看不懂没有紧张.. 8)
  • 对不起,以前一样。我强烈鼓励你跳,特别是如果你在做 Backbone 的东西。更好,更容易阅读。对我来说,花了一个下午的时间来学习(而且我绝不是一个 l33t js 人)。

标签: javascript backbone.js coffeescript


【解决方案1】:

将重复模型添加到集合中没有任何作用;特别是,它不会触发"add" 事件,因为不会添加任何内容。考虑一下:

# c is an empty collection
c.add(id: 1, t: 'where is')
c.add(id: 2, t: 'pancakes house?')
c.add(id: 1, t: 'different')

这将生成两个"add" 事件,集合将以(1, 'where is')(2, 'pancakes house?') 作为模型结束,第三个add 将被忽略。

演示:http://jsfiddle.net/ambiguous/WUH6f/

0.9.2 changelog 有话要说:

  • 在将重复模型添加到集合时不会引发错误,Backbone 现在会静默跳过它们。

因此,如果fetchData 被调用两次,您将收到两次对console.log('fetching') 的调用。但是,如果opts.idfetchData 的两次调用都相同,那么第二个@add 将被忽略,因为集合中已经有一个带有id == opts.id 的模型。


您说opts.id 每次都不同,但这并不一定意味着@series.get('id') 会不同。请记住,AJAX 中的 A 代表 asynchronous,因此您可能会看到与此类似的一系列事件:

  1. 某事调用fetchData(id: 1)@series.id 现在是 1。
  2. 已进行 AJAX 调用。
  3. 某事调用fetchData(id: 2)@series.id 现在是 2。请记住,@series 是一个实例变量,而不是一个局部变量。
  4. 服务器从第一个 AJAX 调用返回并触发 success 处理程序。 @series.id 现在是 2,并且将添加来自 3Series
  5. 服务器从第二个 AJAX 调用返回并触发成功处理程序。 @series.id 仍为 2,因此将再次添加来自 3Series。但是这个是重复的,所以add 会忽略你。

您应该能够通过对相关系列使用普通的旧局部变量而不是实例变量来解决此问题:

fetchData: ( opts ) =>
    console.log('fetching')
    series = new Series({ id: opts.id })
    series.fetch
        success: (model, response) =>
            @add(
                id: series.get('id')
                #...
            )

你不需要@.add 中的.,所以我把它拿出来了。我还在@add 调用中删除了大括号,因为您也不需要它们;你也可以去掉括号,但我把它们留在里面,因为我发现它们有助于阐明代码的块结构。

我应该首先发现这个问题,抱歉。

【讨论】:

  • +1 因为这回答了我自己解决但不明白原因的问题
  • 不幸的是 opts 每次都不一样,所以这个答案是不正确的。或正确,但不是解决我遇到的问题的方法。
  • @FredStevens-Smith:opts 可能不同,但 @series 可能不同。我添加了一个可能解释发生了什么的更新。
  • @muistooshort:谢谢。标记为接受。解决方案涉及重写我蹩脚的代码,但这非常有帮助。
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2021-11-05
  • 2013-04-20
  • 2015-07-15
  • 2017-12-02
相关资源
最近更新 更多