jQuery 1.5 приносит новый отложенный объект и присоединенные методы .when
, .Deferred
и ._Deferred
.
Для тех, кто не использовал .Deferred
раньше, я аннотировал источник для этого .
Каковы возможные применения этих новых методов, как мы можем приспособить их к шаблонам?
Я уже прочитал API и исходный код , поэтому я знаю, что он делает. Мой вопрос: как мы можем использовать эти новые функции в повседневном коде?
У меня есть простой пример буферного класса, который вызывает AJAX-запрос по порядку. (Следующий начинается после окончания предыдущего).
/* Class: Buffer
* methods: append
*
* Constructor: takes a function which will be the task handler to be called
*
* .append appends a task to the buffer. Buffer will only call a task when the
* previous task has finished
*/
var Buffer = function(handler) {
var tasks = [];
// empty resolved deferred object
var deferred = $.when();
// handle the next object
function handleNextTask() {
// if the current deferred task has resolved and there are more tasks
if (deferred.isResolved() && tasks.length > 0) {
// grab a task
var task = tasks.shift();
// set the deferred to be deferred returned from the handler
deferred = handler(task);
// if its not a deferred object then set it to be an empty deferred object
if (!(deferred && deferred.promise)) {
deferred = $.when();
}
// if we have tasks left then handle the next one when the current one
// is done.
if (tasks.length > 0) {
deferred.done(handleNextTask);
}
}
}
// appends a task.
this.append = function(task) {
// add to the array
tasks.push(task);
// handle the next task
handleNextTask();
};
};
Я ищу демонстрации и возможное использование .Deferred
и .when
.
Также было бы здорово увидеть примеры ._Deferred
.
Ссылка на новый jQuery.ajax
источник для примеров - это мошенничество.
Меня особенно интересует, какие методы доступны, когда мы абстрагируемся, выполняется ли операция синхронно или асинхронно.
источник
._Deferred
это просто истинный «отложенный объект», который.Deferred
использует. Это внутренний объект, который вам, скорее всего, никогда не понадобится.Ответы:
Лучший вариант использования, который я могу придумать, это кэширование ответов AJAX. Вот модифицированный пример из вступительного поста Ребекки Мерфи на эту тему :
В основном, если значение уже было запрошено один раз, прежде чем оно немедленно возвращается из кэша. В противном случае запрос AJAX извлекает данные и добавляет их в кэш.
$.when
/.then
Не заботится обо всем этом; все, что вам нужно, это использовать ответ, который передается.then()
обработчику в обоих случаях.jQuery.when()
обрабатывает не-Обещание / Отложено как Завершенное, немедленно выполняя любое.done()
или.then()
в цепочке.Отложенные идеально подходят для случаев, когда задача может работать или не работать асинхронно, и вы хотите абстрагировать это условие от кода.
Еще один пример из реальной жизни с использованием
$.when
помощника:источник
cache[ val ]
возвращать обещание (документация jquery говорит, что параметром являются данные, возвращаемые отправителем), это означает, что член доступа.then
будет ошибка ... правильно? Чего мне не хватает?Вот немного отличная реализация AJAX-кэша, как в ответе Ehynd .
Как отмечено в последующем вопросе к fortuneRice, реализация ehynd на самом деле не предотвращала множественные идентичные запросы, если запросы были выполнены до того, как один из них вернулся. То есть,
скорее всего, приведет к 3 AJAX-запросам, если результат для «xxx» еще не был кэширован ранее.
Это может быть решено путем кэширования Deferreds запроса вместо результата:
источник
Отложенный может быть использован вместо мьютекса. По сути, это то же самое, что и сценарии множественного использования ajax.
MUTEX
DEFERRED
При использовании Deferred в качестве мьютекса, следите за влиянием производительности (http://jsperf.com/deferred-vs-mutex/2). Хотя удобство, а также дополнительные преимущества, предоставляемые Deferred, того стоят, и при фактическом использовании (на основе событий пользователя) влияние на производительность не должно быть заметным.
источник
Это саморекламный ответ, но я потратил несколько месяцев на его изучение и представил результаты на jQuery Conference San Francisco 2012.
Вот бесплатное видео разговора:
https://www.youtube.com/watch?v=juRtEEsHI9E
источник
Еще одно использование, которое я использовал для достижения хороших целей, - это получение данных из нескольких источников. В приведенном ниже примере я извлекаю несколько независимых объектов схемы JSON, используемых в существующем приложении для проверки между клиентом и сервером REST. В этом случае я не хочу, чтобы приложение на стороне браузера начинало загружать данные до того, как загрузятся все схемы. $ .when.apply (). then () идеально подходит для этого. Спасибо Raynos за указатели на использование then (fn1, fn2) для отслеживания ошибок.
источник
Другой пример использования
Deferred
s для реализации кэша для любого вида вычислений (обычно это некоторые задачи с высокой производительностью или длительные задачи):Вот пример использования этого класса для выполнения некоторых (смоделированных тяжелых) вычислений:
Тот же базовый кеш можно использовать для кеширования Ajax-запросов:
Вы можете играть с приведенным выше кодом в этом jsFiddle .
источник
1) Используйте его для обеспечения упорядоченного выполнения обратных вызовов:
2) Используйте его, чтобы проверить статус приложения:
источник
Вы можете использовать отложенный объект для создания плавного дизайна, который хорошо работает в браузерах webkit. Браузеры Webkit будут запускать событие изменения размера для каждого пикселя, в котором изменяется размер окна, в отличие от FF и IE, которые запускают событие только один раз для каждого изменения размера. В результате вы не можете контролировать порядок выполнения функций, связанных с вашим событием изменения размера окна. Нечто подобное решает проблему:
Это выполнит сериализацию выполнения вашего кода так, чтобы он выполнялся так, как вы намеревались. Остерегайтесь ловушек при передаче методов объекта как обратных вызовов к отложенному. Как только такой метод будет выполнен как обратный вызов для deferred, ссылка 'this' будет перезаписана со ссылкой на объект deferred и больше не будет ссылаться на объект, которому принадлежит метод.
источник
resizeQueue.done(resizeAlgorithm)
же, как иresizeAlgorithm
. Это полный обман!.done
будет сделан следующий вызов .Вы также можете интегрировать его с любыми сторонними библиотеками, использующими JQuery.
Одна из таких библиотек - Backbone, которая на самом деле собирается поддерживать Deferred в следующей версии.
источник
read more here
вместоon my blog
. Это лучшая практика и может спасти вас от (случайно) спам. :)Я только что использовал Deferred в реальном коде. В проекте jQuery Terminal у меня есть функция exec, которая вызывает команды, определенные пользователем (например, он вводил его и нажимал ввод), я добавил Deferreds в API и вызывал exec с массивами. как это:
или
Команды могут запускать асинхронный код, и exec должен вызывать код пользователя по порядку. Мой первый API использует пару вызовов паузы / возобновления, и в новом API я вызываю их автоматически, когда пользователь возвращает обещание. Так что пользовательский код можно просто использовать
или
Я использую такой код:
Команды dalyed_commands используются в функции возобновления, которая снова вызывает exec со всеми командами dalyed_commands.
и часть функции команд (я удалил не связанные части)
источник
Ответ по ehynds не будет работать, потому что он кэширует данные ответов. Он должен кэшировать jqXHR, который также является Обещанием. Вот правильный код:
Ответ Джулиана Д. будет работать правильно и является лучшим решением.
источник