【问题标题】:How to "or" two Promises in JQuery如何在 JQuery 中“或”两个 Promise
【发布时间】:2013-04-07 02:16:05
【问题描述】:

如果.when 相当于 JQuery Promises 的“与”运算符,那么“或”运算符的等价物是什么?

如果我有两个 Promise,并且我想在两个 Promise 都解决后做某事,那么我应该使用“when”方法。但是我有一个场景,当一个承诺或另一个承诺已经解决时,我想做一些事情。

场景是数据库初始化。第一个承诺与检查数据库是否已经存在有关。如果第一个承诺被拒绝,第二个承诺来自创建数据库。然后我想运行一些以第一个承诺或第二个承诺为条件的代码。

目前我的代码看起来有点像这样:

function initialiseDB() {
    var deferred = jQuery.Deferred();

    // Check to see if the database exists already
    var existencePromise = checkExistenceOfDatabase();

    existencePromise.done(function() {
        // The database exists; no need to pull a copy
        deferred.resolve(); 
    });
    existencePromise.fail( function(error) {
        // Failed to confirm existence of database; pull a copy
        var pullPromise = pullDatabase();

        pullPromise.fail( function(error) {
            // Failed to pull database
            deferred.reject();
        });
        pullPromise.done( function() {
            // A copy of the database has been pulled
            deferred.resolve();
        });
    });

    return deferred.promise();
}

这实际上是一个自定义的“惰性或”运算符。

我是 JQuery 的 Promises 的新手,我花了很长时间寻找一个通用的“或”方法。上面的代码是应该如何完成的,还是我错过了一个通用的形式?

【问题讨论】:

  • 您的代码没有发现任何明显的问题。只要记住 deferred.reject() 调用任何添加到 deferred 的 failCallbacks。此外,对于 deferred 没有 OR 方法,您必须分别处理每个场景(完成、失败)。
  • 在承诺解决时创建事件并触发

标签: jquery promise


【解决方案1】:

马修,您的代码将简化为:

function initialiseDB() {
    var deferred = jQuery.Deferred();
    checkExistenceOfDatabase().done(deferred.resolve).fail(function(error) {
        pullDatabase().fail(deferred.reject).done(deferred.resolve);
    });
    return deferred.promise();
}

我很确定它会进一步简化为:

function initialiseDB() {
    return checkExistenceOfDatabase().then(null, function(error) {
        return pullDatabase();
    });
}

或者非常简洁:

function initialiseDB() {
    return checkExistenceOfDatabase().then(null, pullDatabase);
}

虽然 nett 效应类似于或,但它确实是顺序逻辑......这正是你想要的;即 pullDatabase 仅应在 checkExistenceOfDatabase() 失败时调用。

【讨论】:

  • 最后一行是黄金版。我已经检查了所有可能的情况,这正是我所追求的。非常感谢。
  • 我承认对马修感到相当高兴。单行总是令人满意,而实际工作的单行更是如此。
【解决方案2】:

这是一个你可以尝试的函数——我们称之为whenAny

var whenAny = function() {
  var finish = $.Deferred();
  $.each(arguments, function(index, def){
    def.done(finish.resolve);
  });
  return finish.promise();
}

用法:whenAny(def1, def2, def3)

您可能需要在这里和那里进行一些调整,也许是关于参数传递,找出实际解决的问题等等,但您明白了。

感谢您提出这个用例...我想我实际上可以将它添加到 simply-deferred 中。看起来还蛮有用的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    相关资源
    最近更新 更多