Недетерминированное назначение свойства Backbone Collection в консоли - PullRequest
0 голосов
/ 08 февраля 2012

Я создаю приложение Backbone и наблюдаю за поведением, которое не могу разместить. Рассмотрим следующую коллекцию:

window.Pictures = Backbone.Collection.extend({
  model: Picture,
  url: 'latest.json',
  parse: function(response) {
    this.foobar = 1;
  },  
  fetchPage: function() {
    this.foobar = 2;
    return this;
  }
});

На консоли Chrome (или Firefox) я выполнил следующую команду:

> p = new Pictures(); p.fetch(); p.fetchPage();
> p.foobar
1

Когда я делаю:

> p = new Pictures(); p.fetch()
> p.fetchPage();
> p.foobar
2

Я действительно не понимаю этого. Почему первое исполнение отличается от второго?

1 Ответ

1 голос
/ 08 февраля 2012

Вызов fetch является асинхронным, поскольку включает в себя AJAX-вызов на сервер:

fetch collection.fetch ([опции])
Извлекает набор моделей по умолчанию для этой коллекции с сервера, сбрасывая коллекцию по прибытии.

И fetch вызовет parse:

parse collection.parse (response)
parse вызывается Backbone всякий раз, когда сервер возвращает модели коллекции в fetch.

Так что p.parse() можно вызывать до или после p.fetchPage(), в зависимости от проблем синхронизации, которые находятся вне вашего контроля.

В первом случае:

> p = new Pictures(); p.fetch(); p.fetchPage();

fetchPage вызывается до того, как fetch получит ответ от сервера и приступит к вызову parse, поэтому последовательность вызова заканчивается следующим образом:

  1. Вы звоните p.fetch().
  2. Выполнен вызов AJAX.
  3. Вы звоните p.fetchPage().
  4. Ответ AJAX получен.
  5. Обработчик успеха AJAX вызывает p.parse().

Во втором случае:

> p = new Pictures(); p.fetch()
> p.fetchPage();

Между строками проходит достаточно времени для возврата вызова AJAX до того, как p.fetchPage() вызывается таквсе происходит в порядке, ожидаемом случайно.

Если вам нужно, чтобы события происходили в определенном порядке, вам нужно будет использовать обратный вызов success (и, возможно, error), который обеспечивает fetch:

Опции hash принимают success и error обратные вызовы, которые будут переданы (collection, response) в качестве аргументов.

Так что это должнодаст вам последовательный результат 2:

p = new Pictures();
p.fetch({
    success: function(collection, response) {
        collection.fetchPage();
        console.log(collection.foobar);
    }
});

Конечно, если fetchPage включает вызов AJAX, вам придется добавить еще один уровень обратных вызовов, чтобы получить согласованное значение foobar.

...