当没有必要等待时如何使用jquery延迟

时间:2014-12-08 00:20:07

标签: javascript jquery jquery-deferred

当一个函数返回一个promise时,我可以在第一个函数完成它之后调用其他函数:

do_stuff().then(function(){
  alert('yoooo');
});

和do_stuff()看起来像这样:

function do_stuff(){

  if(!got_the_data){

    var d = $.Deferred();

    $.ajax({
      success: function(html){
        $('#box').append(html);
        $('#box').addClass('visible');
        $('#box').on('transitionend webkitTransitionEnd', function(){
          got_the_data = true;
          d.resolve();
        });
      }
    });

    return d.promise();

  }else{
    // got the data, what now?
  }
}

但如果我已经执行了ajax请求(结果被缓存)并且我不必等待任何事情,我该返回什么?我无法返回d.resolve(),因为附加到then()的函数不会触发:/

我无法返回d.promise,因为我必须解决这个问题。某处

2 个答案:

答案 0 :(得分:2)

您可以选择两种方法;缓存数据或缓存承诺。

这里有两个例子,两个关键字都放在url上,但可以酌情使用任何其他关键字 - 只要它唯一地标识每个个案。

缓存数据

var dataCache = {};

function do_stuff_1(url) {
    if(dataCache[url] === undefined) {
        return $.ajax({
            url: url
        }).then(function(data) {
            dataCache[url] = data;
            return data;
        });
    } else {
        return $.when(dataCache[url]);
    }
}

缓存承诺

var promiseCache = {};

function do_stuff_2(url) {
    if(!promiseCache[url]) {
        promiseCache[url] = $.ajax({
            url: url
        });
    }
    return promiseCache[url];
}

在这两种方法中,函数将(禁止未被捕获的错误)返回一个promise,方法是执行$.ajax()或从缓存中检索数据/ promise。

在大多数应用程序中,几乎没有什么可以区分一种方法与另一种方法。

在缓存可能会变得很大的应用程序中,然后缓存数据并避免缓存promise包装器的开销。

如有必要,可以预先加载缓存,从而避免了获取已知数据的需要:

var dataCache = {
    '/path/to/data/a': 'A',
    '/path/to/data/b': 'B'
}

var promiseCache = {
    '/path/to/data/a': $.when('A'),
    '/path/to/data/b': $.when('B')
}

答案 1 :(得分:1)

最简单的解决方案是在else子句中返回一个空的已解析的promise:

return $.Deferred().resolve();

为避免Promise反模式,您的代码可能会更好地构建:

function show_stuff(html) {
    return $.Deferred(function(def) {
        $('#box').append(html);
        $('#box').addClass('visible');
        $('#box').on('transitionend webkitTransitionEnd', def.resolve);
    });
}

function do_stuff() {
    if (got_the_data) {
        return $.Deferred().resolve();
    } else {
        return $.ajax(...).then(show_stuff);
    }
}

请注意,没有行(尚)设置got_the_data = true - 您应该考虑是否真的适合等待数据显示以设置此标志,否则没有什么可以阻止{{1}的多次调用所有导致新内容被添加到do_stuff。恕我直言,你会用#box旗帜做得更好。