【问题标题】:Use of dummy and empty jQuery promises使用 dummy 和空的 jQuery 承诺
【发布时间】:2014-07-30 08:53:36
【问题描述】:

我使用 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...*/);
  }
}

【问题讨论】:

标签: javascript jquery promise jquery-deferred


【解决方案1】:

如果你打算将它与$.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()

【讨论】:

  • 更新了问题以删除空承诺的回报。但是“哑”的诺言还在,不知道是不是自找麻烦……
  • @BobbyB 好吧,答案是一样的。如果您打算将它与$.when 一起使用,则无需返回承诺。但是,如果您要像 qux().then(blah) 一样称呼它,则最好注意它以始终返回承诺。
  • 是的,我明白你的意思。它会立即执行,但组的 done 事件将在动画函数解析后被调用。
  • 所以我的问题的实际答案是它是“安全的”:你可以把任何东西塞进$.when(...)
  • 如果你想返回一个空的promise,你可以使用return $.when();,这是语法上最简单的方法来生成一个resolved jQuery promise。
【解决方案2】:

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

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

你仍然可以在$.when 中使用它,但是因为它是同步执行的,所以没什么意义。你不应该从同步函数中返回 Promise。

但是,如果您的函数有时是同步的 - 它应该总是返回一个保证一致性的承诺。

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

【讨论】:

  • 不,请不要那样做。不要将其用作qux().then(blah)$.when(qux()).then(blah)。这是较慢和多余的。相反,您可以这样做 qux(); blah()
  • 我不同意 - 在大多数情况下它不会是 qux();blah(),而是 let result == qux() ; if (result.state=='rejected') blah(); else meh(); dada();qux().then(blah).fail(meh).done(dada) 相比,我知道我会选择哪个 - 特别是如果我们需要传递 @987654331 的结果@ 或 blahdada
猜你喜欢
  • 2015-08-06
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
相关资源
最近更新 更多