返回一个空洞的承诺

Jon*_*man 21 javascript ajax jquery jquery-deferred typescript

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

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

我这样做,所以我可以重用这个函数和链承诺回调,如:

addBooks.done(() => { alert("Books added!"); })
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我想尽早摆脱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'
    });
}
Run Code Online (Sandbox Code Playgroud)

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

Ber*_*rgi 27

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

是的,如果你的意思是一个已经没有实现的承诺(undefined,null),那么这里就是一个"空洞的承诺" .

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

if (books <= 0) return $.when(null);
Run Code Online (Sandbox Code Playgroud)


T.J*_*der 8

您可以返回已解决的承诺:而不是

if (books <= 0) return null;
Run Code Online (Sandbox Code Playgroud)

使用

if (books <= 0) return $.Deferred().resolve();
Run Code Online (Sandbox Code Playgroud)

但要注意,jQuery的PromiseAPI会令人惊讶:有时它会调用你的done/ then/ etc.与done/ then/ etc 同步回调.打电话,有时候不打电话.大多数promises库确保调用始终是异步的,即使你正在调用done/ then/ etc.在解决的承诺上.jQuery没有,所以你会得到微妙的差异.

例如,这段代码:

addBooks(() => console.log(1));
console.log(2);
Run Code Online (Sandbox Code Playgroud)

...会记录

2
1

...如果你做了ajax电话,但是

1
2

......如果你回复了解决的承诺.