【问题标题】:Return an empty promise返回一个空的承诺
【发布时间】:2015-07-12 07:49:33
【问题描述】:

我有一个返回 jQuery 承诺的函数。它看起来像这样:

addBooks(books: Array<Books>) {
    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

我这样做是为了重用这个函数和链式 promise 回调,例如:

addBooks.done(() => { alert("Books added!"); })

我的问题是,如果我想尽早脱离 addBooks 并防止访问服务器怎么办。例如:

addBooks(books: Array<Books>) {

    // An empty array was passed in for some reason.
    // Theres nothing to add so dont try to POST
    if (books <= 0) return null;

    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

我的示例无法编译,因为我的链式完成回调示例期望 addBooks 返回一个承诺对象,而不是 null。我怎样才能返回一个空的承诺(或者在这种情况下我应该返回什么正确的对象)?

【问题讨论】:

    标签: javascript jquery ajax typescript jquery-deferred


    【解决方案1】:

    你可以返回一个 resolved 承诺:而不是

    if (books <= 0) return null;
    

    使用

    if (books <= 0) return $.Deferred().resolve();
    

    小心,不过,jQuery 的 Promise API 做了一些令人惊讶的事情:有时它会调用你的 done/then/etc。与done/then/等同步回调。打电话,有时不会。大多数承诺库确保调用始终是异步的,即使您正在调用done/then/等。在一个已解决的承诺上。 jQuery 没有,所以你会得到细微的差别。

    例如,这段代码:

    addBooks(() => console.log(1));
    console.log(2);
    

    ...将记录

    2 1

    ...如果您进行了 ajax 调用,但是

    1 2

    ...如果你返回了一个已解决的承诺。

    【讨论】:

    • 这可以编译,但我必须添加额外的代码,因为$.Deferred 的返回类型与$.ajax 的返回类型不同。我喜欢@Bergi 给出的答案,因为它的代码少了一点。
    【解决方案2】:

    我怎样才能返回一个空的承诺(或者在这种情况下我应该返回什么正确的对象)?

    是的,“空承诺”在这里是合适的,如果你的意思是一个已经兑现但一无所有的承诺(undefinednull)。

    创建这样的 jQuery 语法是使用带有单个(或没有)参数的 $.when

    if (books <= 0) return $.when(null);
    

    【讨论】:

    • 我不知道$.when 的这种用法,但它就在文档中!
    • return $.Deferred().resolve(); 是更正确的答案。
    • @wonsuc 你为什么这么认为,你如何定义“正确”?
    【解决方案3】:

    来自https://api.jquery.com/jquery.when/

    如果您根本不传递任何参数,jQuery.when() 将返回一个已解决的承诺。

    例如

    if (books <= 0) return $.when();
    

    并且,如果您需要一个未定义传递的值:

    如果 单个参数 被传递给 jQuery.when() 并且它不是 Deferred 或 Promise,它将被视为已解决的 Deferred 和任何 doneCallbacks附加将立即执行。 doneCallbacks 被传递给原始参数。

    例如传递一个空数组:

    if (books <= 0) return $.when([]);
    

    例如传递一个空对象:

    if (books <= 0) return $.when({});
    

    【讨论】:

      猜你喜欢
      • 2015-11-27
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多