Можно ли остановить запросы на чтение Backbone

У меня есть базовое приложение, которое имеет несколько просмотров. Переключение между представлениями запускает запросы Ajax для получения разных коллекций. Я хотел бы остановить текущий запрос ajax «чтение», если запущен новый. Является ли это возможным?


person Xerri    schedule 05.10.2012    source источник


Ответы (3)


Итак, вот что я сделал

Я сохраняю запросы на выборку в переменной

app.fetchXhr = this.model.fetch();

В моем маршрутизаторе у меня есть функция, которая заботится о закрытии представлений и отображении представлений. Он также заботится о запуске любых триггеров, необходимых для каждого изменения представления, но это не имеет отношения к этому вопросу.

Прежде чем что-либо делать, эта функция маршрутизатора выполняет следующее

//Stop pending fetch
if(app.fetchXhr.readyState > 0 && app.fetchXhr.readyState < 4){
    app.fetchXhr.abort();
}

надеюсь, это поможет

person Xerri    schedule 15.10.2012
comment
У меня есть связанная проблема, но у меня есть более одной коллекции. Поэтому, прежде чем я прерву запрос, мне нужно убедиться, что он связан с определенной коллекцией. Я задавал этот вопрос здесь, может быть, вы уже занимались этим вопросом? stackoverflow.com/questions/21919690/ - person wuliwong; 21.02.2014
comment
Это еще не реализовано, но вы можете попробовать сохранить все запросы xhr в массиве. При каждом запросе xhr или при каждом изменении представления вы можете прокручивать массив, чтобы очистить те, которые завершены, и остановить те, которые вы хотите остановить. Это должно обеспечить адекватную очистку. - person Xerri; 21.02.2014

Еще один поздний ответ на случай, если кто-то еще столкнется с этим.

В итоге я перезаписал Backbone.sync, чтобы добавить пул объектов XHR и возможность прерывать ожидающие запросы при выборке.

var sync = Backbone.sync
  , xhrPool = [];

Backbone.sync = function(method, model, options) {
  options = options || {};
  if (method === 'read') {
    if (options.abortPending == true) {      
      for (var i = 0; i < xhrPool.length; i++) {
        if (xhrPool[i]['readyState'] > 0 && xhrPool[i]['readyState'] < 4) {
          xhrPool[i].abort();
          xhrPool.splice(i, 1);
        }
      }
    }

    // cleanup xhrPool
    // todo: make removal from the pool an 'always' jqXHR callback
    // instead of cleanup on every read?
    for (var i = 0; i < xhrPool.length; i++) {
      if (xhrPool[i]['readyState'] === 4) {
        xhrPool.splice(i, 1);
      }
    }

    var xhr = sync(method, model, options);
    xhrPool.push(xhr);
    return xhr;
  } else {
    return sync(method, model, options);
  }
};
person Garrett Johnson    schedule 02.08.2013
comment
Очень круто.... может быть не гибким, если вы делаете несколько запросов на выборку в определенном представлении. FYI... Одна из причин, по которой мне это было нужно, заключалась в том, чтобы избежать появления ошибок, когда выборка завершена, но представление изменилось (поэтому элемент DOM, который содержал бы данные, больше не существует). Простая попытка/перехват вокруг выборки исправила это. - person Xerri; 05.08.2013

Я предполагаю, что вы используете магистраль с jQuery. Если это так, следующий вопрос, кажется, дает вам ответ:

Отменить запросы Ajax с помощью jQuery

Backbone fetch возвращает xhr, о котором они говорят, IIRC.

person JayC    schedule 05.10.2012
comment
но не будет ли возвращаться xhr после его завершения? Не знаете, как использовать предоставленную вами ссылку, чтобы реализовать ее в Backbone. - person Xerri; 08.10.2012
comment
Backbone использует обычные вызовы ajax (через Zepto или jQuery), что означает, что вызов к серверу является асинхронным и потенциально может быть прерван. - person JayC; 08.10.2012