主干中的同时 fetch() 失败

Simultaneous fetch() in Backbone failing

本文关键字:fetch 失败      更新时间:2023-09-26

我正在尝试实现一些对 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', @)

将重复模型添加到集合不会执行任何操作;特别是,它不会触发"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 更新日志是这样说的:

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

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


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

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

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

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

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

我应该首先发现这个问题,对不起。