jQuery 1.5引入了新的延迟对象和附加方法.when、.Deferred和._Deferred。
对于那些以前没有使用过.Deferred的人,我对source for it进行了注释。
这些新方法的可能用途是什么?我们如何将它们适合于模式?
我已经读过API和source了,所以我知道它是做什么的。我的问题是,我们如何在日常代码中使用这些新功能?
我有一个简单的buffer类的example,它按顺序调用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源代码的例子是作弊。
我特别感兴趣的是,当我们抽象出一个操作是同步完成还是异步完成时,可以使用哪些技术。
发布于 2011-02-02 20:57:52
我能想到的最好的用例是缓存AJAX响应。下面是一个来自Rebecca Murphey's intro post on the topic的修改后的示例
var cache = {};
function getData( val ){
// return either the cached value or jqXHR object wrapped Promise
return $.when(
cache[ val ] ||
$.ajax('/foo/', {
data: { value: val },
dataType: 'json',
success: function( resp ){
cache[ val ] = resp;
}
})
);
}
getData('foo').then(function(resp){
// do something with the response, which may
// or may not have been retrieved using an
// XHR request.
});基本上,如果值在从缓存中立即返回之前已经被请求过一次。否则,AJAX请求将获取数据并将其添加到缓存中。$.when/.then并不关心这些;您需要关心的只是使用响应,在这两种情况下,响应都会被传递给.then()处理程序。jQuery.when()将非承诺/延迟作为已完成的处理,立即执行链上的任何.done()或.then()。
当任务可能异步操作或可能不异步操作,并且您希望将该条件从代码中抽象出来时,延迟是完美的。
使用$.when帮助器的另一个真实示例:
$.when($.getJSON('/some/data/'), $.get('template.tpl')).then(function (data, tmpl) {
$(tmpl) // create a jQuery object out of the template
.tmpl(data) // compile it
.appendTo("#target"); // insert it into the DOM
});发布于 2012-01-22 19:03:40
下面是一个与ehynd's answer中的AJAX缓存稍有不同的实现。
正如fortuneRice's follow-up question中所指出的,如果请求是在其中一个请求返回之前执行的,则ehynd的实现实际上不会阻止多个相同的请求。那是,
for (var i=0; i<3; i++) {
getData("xxx");
}如果之前没有缓存过"xxx“的结果,很可能会导致3个AJAX请求。
这可以通过缓存请求的延迟而不是结果来解决:
var cache = {};
function getData( val ){
// Return a promise from the cache (if available)
// or create a new one (a jqXHR object) and store it in the cache.
var promise = cache[val];
if (!promise) {
promise = $.ajax('/foo/', {
data: { value: val },
dataType: 'json'
});
cache[val] = promise;
}
return promise;
}
$.when(getData('foo')).then(function(resp){
// do something with the response, which may
// or may not have been retreived using an
// XHR request.
});发布于 2011-05-24 02:44:26
可以使用延迟的互斥来代替互斥。这基本上与多个ajax使用场景相同。
多路复用
var mutex = 2;
setTimeout(function() {
callback();
}, 800);
setTimeout(function() {
callback();
}, 500);
function callback() {
if (--mutex === 0) {
//run code
}
}延迟
function timeout(x) {
var dfd = jQuery.Deferred();
setTimeout(function() {
dfd.resolve();
}, x);
return dfd.promise();
}
jQuery.when(
timeout(800), timeout(500)).done(function() {
// run code
});在仅将延迟作为互斥锁使用时,请注意性能影响(http://jsperf.com/deferred-vs-mutex/2)。虽然延迟带来的便利和额外的好处是非常值得的,但在实际(基于用户驱动的事件)使用中,性能影响应该不会很明显。
https://stackoverflow.com/questions/4869609
复制相似问题