使用虚拟和空jQuery承诺

时间:2014-07-30 08:53:36

标签: javascript jquery promise jquery-deferred

我使用jQuery promises运行多个动画,并在完成后执行一些操作:

$.when(foo(),  
       bar(),  
       baz())  
 .done(allDone);  

每个函数(foo等)都返回jQuery.Promise()

现在说我想要包含一个不会动画任何动画的功能,但它的时间与动画相关 - 我不能将它包含在链中,因为它不会返回的承诺。

所以我可以像这样破解它:

function qux() {
  if (something) {
    return $(".whatever")
      .removeClass("bob")
      .addClass("fred")
      .append(/*...do stuff...*/)
      .animate({ left: "+=0" }, 0, callback ) // <-- dummy animation does nothing
      .promise();                             // <-- this is a dummy promise
  }
  else {
    return $().promise();                     // <-- this is an "empty" promise
  }
}

现在我可以链接它:

$.when(foo(),  
       bar(),  
       baz(),
       qux())  
 .done(allDone);  

这有效。但是我在这里弯曲了规则 - 是否有任何我没有考虑到的问题,或者我是否以某种方式踩到了fx队列?

更新
根据下面的答案,qux()函数可以重写为:

function qux() {
  if (something) {
    $(".whatever")
      .removeClass("bob")
      .addClass("fred")
      .append(/*...do stuff...*/);
  }
}

2 个答案:

答案 0 :(得分:7)

如果您要将其与$.when一起使用,则无需返回空的承诺。 $.when可以处理非承诺。 Demo

function promise(flag) {
    if(flag) {
        var dfd = $.Deferred();
        setTimeout(function(){
            console.log('promise');
            dfd.resolve();
        }, 1000);
        return dfd.promise();
    }

    console.log('promise');
}

$.when(promise(), promise(true), promise(), 15).done(function(){
    console.log('Done');    
});

如果您想要返回空承诺,可以使用$.Deferred().resolve().promise()

答案 1 :(得分:1)

如果您的函数始终是同步的 - 只需不返回承诺:

function qux() {
  if (something) {
    return $(".whatever")
      .removeClass("bob")
      .addClass("fred")
      .append(/*...do stuff...*/);
  }
}

您仍然可以在$.when中使用它,但由于它同步执行,因此没什么意义。您不应该从同步函数返回promise。

但是,如果您的函数有时同步 - 它应始终返回一致性承诺。

正如我在之前的评论中所说的那样 - $.when完全没有承诺(它会将它们视为承诺)。因此,可以返回promises的函数可以与$.when一起使用,但是如果它始终是同步的,则这样做是多余的。