如何推迟使用jQuery?
jQuery 1.5带来了新的Deferred对象和附加的方法.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
源代码就是作弊。
赏金:当我们抽象出一个操作是同步还是异步完成时,告诉我们什么技术可用。
我能想到的最佳用例是缓存AJAX响应。 以下是Rebecca Murphey关于该主题的介绍帖子的一个修改示例:
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()
将非Promise / Deferred处理为Completed,立即在链上执行任何.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
});
这里是一个稍微不同的AJAX缓存实现,就像在ehynd的答案中一样。
如fortuneRice的后续问题所述,如果请求是在其中一个请求返回之前执行的,那么ehynd的实现实际上并未阻止多个相同的请求。 那是,
for (var i=0; i<3; i++) {
getData("xxx");
}
如果“xxx”的结果之前尚未被缓存,最有可能导致3个AJAX请求。
这可以通过缓存请求的Deferreds而不是结果来解决:
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.
});
延迟可以用来代替互斥。 这与多个ajax使用场景基本相同。
MUTEX
var mutex = 2;
setTimeout(function() {
callback();
}, 800);
setTimeout(function() {
callback();
}, 500);
function callback() {
if (--mutex === 0) {
//run code
}
}
DEFERRED
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
});
仅当使用Deferred作为互斥锁时,请注意性能影响(http://jsperf.com/deferred-vs-mutex/2)。 尽管Deferred提供的便利以及其他好处非常值得,但在实际(基于用户驱动的事件)使用中,性能影响不应引起注意。
链接地址: http://www.djcxy.com/p/60197.html