【问题标题】:Return deferred object or null返回延迟对象或 null
【发布时间】:2015-12-05 15:29:05
【问题描述】:

我有一个提交一些数据的函数。根据某些布尔值的状态,我可能不想提交此数据。然而,调用者总是期待一个延迟对象作为检查 .done() 或 .fail() 的返回值。当某些事情期望完成/失败(有意义)时,您似乎不能返回 null 或什么也不返回,所以我不知道如何从这个异步调用中返回。

我可以破解 $.Deferred 对象并立即解析/返回它,但这似乎是糟糕的设计。此处无法更改调用方式。

如何在不使用延迟对象的情况下返回延迟对象或其他满足 .done() 或 .fail() 的返回值?

function foo(a) {
    bar(a).done(function () {
        console.log("done");
    }).fail(function () {
        console.log("fail");
    });
}

function bar(a) {
    if (a){
        // Could create a $.Deferred and resolve it
        return;
    }

    return doAsync();
}

function doAsync() {
    var defer = $.Deferred();
    defer.resolve();
    return defer.promise();
}

foo(false); // fine
foo(true); // error

http://jsfiddle.net/ma4grjj4/2/

【问题讨论】:

  • “我可以破解 $.Deferred 对象并立即解析/返回它,但这似乎是糟糕的设计。” 一点也不。
  • @FelixKling 嗯,真的吗?我最理想的做法是在foo 中跳过对bar 的整个调用,但是bar().done 内部会发生很多事情,这两种情况都需要发生。
  • 这正是您使用immediately resolved promise 所获得的。无论如何,它都不是反模式。

标签: javascript jquery


【解决方案1】:

主要问题是,使用布尔参数改变函数的处理流程通常是一种设计味道。

我想你会同意做以下这样的事情是没有意义的:

function process(doNotProcess) {
    if (doNotProcess) return;

    //process
}

在上面的例子中,不调用process() 来避免处理会更有意义。

“我最理想的做法是在 foo 中跳过 bar 的整个调用,但是 bar().done 内部发生了很多事情,需要在两者中发生 案例”

该代码可能应该从done 回调中提取出来并放入不同的函数中,这样您就可以重用它而无需调用bar

“我可以破解 $.Deferred 对象并立即解析/返回它, 但这似乎是糟糕的设计。”

当您需要标准化可能具有同步或异步实现的 API 的使用时,创建延迟对象并立即解决它们是一种非常标准的方法。

这样做是一种非常好的做法,因为它使客户不必依赖实施细节。

【讨论】:

    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多