返回一个空的承诺
Posted
技术标签:
【中文标题】返回一个空的承诺【英文标题】: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。我怎样才能(或者在这种情况下我应该返回什么正确的对象)?
【问题讨论】:
【参考方案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】:
我怎样才能返回一个空的承诺(或者在这种情况下我应该返回什么正确的对象)?
是的,“空承诺”在这里是合适的,如果你的意思是一个已经兑现但一无所有的承诺(undefined
,null
)。
创建这样的 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();
【讨论】:
以上是关于返回一个空的承诺的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript:如何正确键入一个接受承诺并按原样返回该承诺的函数