首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用jQuery deferred?

如何使用jQuery deferred?
EN

Stack Overflow用户
提问于 2011-02-02 08:36:54
回答 11查看 137.6K关注 0票数 281

jQuery 1.5引入了新的延迟对象和附加方法.when.Deferred._Deferred

对于那些以前没有使用过.Deferred的人,我对source for it进行了注释。

这些新方法的可能用途是什么?我们如何将它们适合于模式?

我已经读过APIsource了,所以我知道它是做什么的。我的问题是,我们如何在日常代码中使用这些新功能?

我有一个简单的buffer类的example,它按顺序调用AJAX请求。(下一个在前一个结束后开始)。

代码语言:javascript
复制
/* 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源代码的例子是作弊。

我特别感兴趣的是,当我们抽象出一个操作是同步完成还是异步完成时,可以使用哪些技术。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2011-02-02 20:57:52

我能想到的最好的用例是缓存AJAX响应。下面是一个来自Rebecca Murphey's intro post on the topic的修改后的示例

代码语言:javascript
复制
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帮助器的另一个真实示例:

代码语言:javascript
复制
$.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

});
票数 215
EN

Stack Overflow用户

发布于 2012-01-22 19:03:40

下面是一个与ehynd's answer中的AJAX缓存稍有不同的实现。

正如fortuneRice's follow-up question中所指出的,如果请求是在其中一个请求返回之前执行的,则ehynd的实现实际上不会阻止多个相同的请求。那是,

代码语言:javascript
复制
for (var i=0; i<3; i++) {
    getData("xxx");
}

如果之前没有缓存过"xxx“的结果,很可能会导致3个AJAX请求。

这可以通过缓存请求的延迟而不是结果来解决:

代码语言:javascript
复制
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.
});
票数 79
EN

Stack Overflow用户

发布于 2011-05-24 02:44:26

可以使用延迟的互斥来代替互斥。这基本上与多个ajax使用场景相同。

多路复用

代码语言:javascript
复制
var mutex = 2;

setTimeout(function() {
 callback();
}, 800);

setTimeout(function() {
 callback();
}, 500);

function callback() {
 if (--mutex === 0) {
  //run code
 }
}

延迟

代码语言:javascript
复制
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)。虽然延迟带来的便利和额外的好处是非常值得的,但在实际(基于用户驱动的事件)使用中,性能影响应该不会很明显。

票数 46
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4869609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档