O jQuery 1.5 traz o novo objeto Adiado e os métodos anexados .when
,.Deferred
e ._Deferred
.
Para aqueles que não usaram .Deferred
antes, eu anotei o fonte .
Quais são os possíveis usos desses novos métodos, como vamos ajustá-los aos padrões?
Eu já li a API e a fonte , então sei o que ela faz. Minha pergunta é como podemos usar esses novos recursos no código cotidiano?
Eu tenho um exemplo simples de uma classe de buffer que chama a solicitação AJAX em ordem. (Começo seguinte depois que o anterior termina).
/* 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();
};
};
Estou à procura de demonstrações e possíveis usos de .Deferred
e .when
.
Também seria adorável ver exemplos de ._Deferred
.
Vinculando ao novo jQuery.ajax
fonte de exemplos é trapaça.
Estou particularmente interessado em quais técnicas estão disponíveis quando abstraímos se uma operação é feita de maneira síncrona ou assíncrona.
fonte
._Deferred
é simplesmente o verdadeiro "objeto adiado" que.Deferred
utiliza. É um objeto interno do qual você provavelmente nunca precisará.Respostas:
O melhor caso de uso em que posso pensar é em cache de respostas AJAX. Aqui está um exemplo modificado da postagem de introdução de Rebecca Murphey sobre o tópico :
Basicamente, se o valor já tiver sido solicitado uma vez antes de ser retornado imediatamente do cache. Caso contrário, uma solicitação AJAX busca os dados e os adiciona ao cache. O
$.when
/.then
não se importa com nada disso; tudo o que você precisa se preocupar é em usar a resposta, que é passada ao.then()
manipulador nos dois casos.jQuery.when()
lida com um que não seja Promessa / Adiado como Concluído, executando imediatamente qualquer um.done()
ou.then()
na cadeia.Os adiados são perfeitos para quando a tarefa pode ou não operar de forma assíncrona e você deseja abstrair essa condição do código.
Outro exemplo do mundo real usando o
$.when
auxiliar:fonte
cache[ val ]
retornar uma promessa (a documentação do jquery diz que o parâmetro são os dados retornados pelo remetente), o que significa que o acesso dos membros do.then
erro ... certo? o que estou perdendo?Aqui está uma implementação ligeiramente diferente de um cache AJAX, como na resposta do ehynd .
Conforme observado na pergunta de acompanhamento do fortuneRice, a implementação do ehynd na verdade não impediu várias solicitações idênticas se as solicitações fossem executadas antes de um deles retornar. Isso é,
provavelmente resultará em 3 solicitações AJAX se o resultado para "xxx" ainda não tiver sido armazenado em cache antes.
Isso pode ser resolvido armazenando em cache os adiados da solicitação em vez do resultado:
fonte
Um adiado pode ser usado no lugar de um mutex. É basicamente o mesmo que os vários cenários de uso do ajax.
MUTEX
DEFERIDO
Ao usar um adiado como apenas um mutex, cuidado com os impactos no desempenho (http://jsperf.com/deferred-vs-mutex/2). Embora a conveniência, bem como os benefícios adicionais fornecidos por um diferido, valham a pena, e no uso real (baseado em eventos do usuário), o impacto no desempenho não deve ser perceptível.
fonte
Essa é uma resposta autopromocional, mas passei alguns meses pesquisando isso e apresentei os resultados na jQuery Conference San Francisco 2012.
Aqui está um vídeo gratuito da palestra:
https://www.youtube.com/watch?v=juRtEEsHI9E
fonte
Outro uso que venho colocando com bons objetivos é buscar dados de várias fontes. No exemplo abaixo, estou buscando vários objetos de esquema JSON independentes usados em um aplicativo existente para validação entre um cliente e um servidor REST. Nesse caso, não quero que o aplicativo do lado do navegador comece a carregar dados antes de carregar todos os esquemas. $ .when.apply (). then () é perfeito para isso. Agradeço a Raynos pelas dicas sobre como usar (fn1, fn2) para monitorar condições de erro.
fonte
Outro exemplo usando
Deferred
s para implementar um cache para qualquer tipo de computação (geralmente algumas tarefas que exigem muito desempenho ou que demoram muito tempo):Aqui está um exemplo de uso dessa classe para executar alguns cálculos (pesados simulados):
O mesmo cache subjacente pode ser usado para armazenar em cache solicitações Ajax:
Você pode jogar com o código acima neste jsFiddle .
fonte
1) Use-o para garantir uma execução ordenada de retornos de chamada:
2) Use-o para verificar o status do aplicativo:
fonte
Você pode usar um objeto adiado para criar um design fluido que funcione bem em navegadores de kit da web. Os navegadores Webkit acionam o evento de redimensionamento para cada pixel em que a janela é redimensionada, ao contrário do FF e do IE, que acionam o evento apenas uma vez para cada redimensionamento. Como resultado, você não tem controle sobre a ordem em que as funções vinculadas ao seu evento de redimensionamento da janela serão executadas. Algo assim resolve o problema:
Isso serializará a execução do seu código para que ele seja executado como você deseja. Cuidado com as armadilhas ao passar métodos de objeto como retornos de chamada para um adiado. Depois que esse método for executado como um retorno de chamada para adiado, a referência 'this' será substituída pela referência ao objeto adiado e não se referirá mais ao objeto ao qual o método pertence.
fonte
resizeQueue.done(resizeAlgorithm)
é exatamente o mesmo queresizeAlgorithm
. É uma farsa completa!.done
seja feita.Você também pode integrá-lo a qualquer biblioteca de terceiros que faça uso do JQuery.
Uma dessas bibliotecas é o Backbone, que realmente suporta o Adiado na próxima versão.
fonte
read more here
no lugar deon my blog
. É uma prática melhor e pode evitar que você responda (acidentalmente) a receber spam. :)Acabei de usar adiado em código real. No projeto jQuery Terminal , tenho a função exec que chama comandos definidos pelo usuário (como se ele estivesse inserindo e pressionando enter), adicionei adiados à API e chamo exec com matrizes. como isso:
ou
os comandos podem executar código assíncrono e o executivo precisa chamar o código do usuário em ordem. Minha primeira API usa um par de chamadas de pausa / retomada e na nova API eu as chamo automaticamente quando o usuário retorna a promessa. Portanto, o código do usuário pode apenas usar
ou
Eu uso código como este:
dalyed_commands é usado na função resume que chama exec novamente com todos os dalyed_commands.
e parte da função de comandos (removi partes não relacionadas)
fonte
A resposta por ehynds não funcionará, porque armazena em cache os dados das respostas. Ele deve armazenar em cache o jqXHR, que também é uma promessa. Aqui está o código correto:
A resposta de Julian D. funcionará corretamente e é uma solução melhor.
fonte