如何推迟使用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

上一篇: How can jQuery deferred be used?

下一篇: Input queue callback called but no data