I have a function that returns a jQuery promise. It looks like this:
addBooks(books: Array<Books>) {
return $.ajax({
url: '/Books/AddBooks/',
type: 'POST',
data: ko.toJSON(books),
contentType: 'application/json'
});
}
I do this so I can reuse this function and chain promise callbacks like:
addBooks.done(() => { alert("Books added!"); })
My question is, what if I want to break out of addBooks early and prevent a trip to the server. For example:
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'
});
}
My example will not compile because my chained done callback example is expecting addBooks
to return a promise object, not null. How can I return an empty promise (or whatever the correct object is I should return in the situation)?
Empty-promise definition (idiomatic) A promise that is either not going to be carried out, worthless or meaningless.
The Promise.resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise.resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
Promises don't "return" values, they pass them to a callback (which you supply with . then()). It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation. Then in your then code you can reference someObject to do what you want.
How can I return an empty promise (or whatever the correct object is I should return in the situation)?
Yes, an "empty promise" is appropriate here, if you mean a promise that is already fulfilled with nothing (undefined
, null
).
The jQuery syntax to create such is using $.when
with a single (or no) argument:
if (books <= 0) return $.when(null);
You can return a resolved promise: Instead of
if (books <= 0) return null;
use
if (books <= 0) return $.Deferred().resolve();
Beware, though, that jQuery's Promise
API does something surprising: Sometimes it calls your done
/then
/etc. callback synchronously with the done
/then
/etc. call, sometimes it doesn't. Most promises libraries ensure that the call is always asynchronous, even if you're calling done
/then
/etc. on a resolved promise. jQuery doesn't, so you get subtle differences.
For instance, this code:
addBooks(() => console.log(1));
console.log(2);
...will log
2 1
...if you did the ajax call, but
1 2
...if you returned a resolved promise.
From https://api.jquery.com/jquery.when/
If you don't pass it any arguments at all,
jQuery.when()
will return a resolved promise.
e.g.
if (books <= 0) return $.when();
and, if you need a value that is not undefined passed on:
If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately. The doneCallbacks are passed the original argument.
e.g. an empty array is passed on:
if (books <= 0) return $.when([]);
e.g. an empty object is passed on:
if (books <= 0) return $.when({});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With