I'm playing around with returning promises from an AJAX method and seeing how I can use them to make my code more easier to read/functional. My current scenario is to have a function getBookIds which issues an AJAX call to a database to return the title of a book based on its ID. There are five books in the table and an anchor tag whose text property corresponds to each book. I want some other fancy AJAX method to fire once all anchor tags have been clicked on. Here's what I've got so far:
HTML
<a href="#">1</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">7</a>
JS
//hacky globals
var bookArray = [];
bookArray.length = $('a').length;
//ajax function
function getBookIds(data) {
return $.ajax({
type: "POST",
url: "Service.asmx/GetBookById",
data: JSON.stringify({
'titleId': data
}),
dataType: "json",
contentType: "application/json"
});
}
//click handler
$('a').on('click', function () {
var index = $('a').index($(this));
var titleId = $(this).text();
getBookIds(titleId).done(function (results) {
bookArray[index] = results.d;
var isEmpty = arrayChecker(bookArray);
fancyAjax(isEmpty);
});
});
//checks for undefined values in the array
function arrayChecker(array) {
var isEmpty = 0;
$.each(array, function (key, val) {
if (val === undefined) {
isEmpty++;
}
});
return (isEmpty > 0);
}
//bool comes from arrayChecker if no undefined then go AJAX
function fancyAjax(bool) {
if (!bool) {
alert('alert message for fancy stuff');
}
}
This is a contrived example, but I'm struggling to see how I could incorporate these promises into my daily work. Is this just a bad example to leverage the power of promises/deferreds in the first place? It seems that instead of the success callback on AJAX, not I've got all my logic rolled up inside done. Any suggestions on tackling this better?
Returns a new Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise, the returned promise will be fulfilled with the value.
There is no need to use a return statement inside a new Promise() callback. The Promise constructor is not expecting any sort of return value from the callback. So, the reason to use a return statement inside that callback is only to control the flow of execution in that function.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Promise callbacks are handled as a Microtask whereas setTimeout() callbacks are handled as Task queues.
I want some other fancy AJAX method to fire once all anchor tags have been clicked on.
That sounds like you want to get a promise for each click, which you can then combine into a promise for all clicks. The point is not to use a global booksArray, but an array of promises.
function getBookIds(data) { … } //ajax function as before
var promises = $('a').map(function() {
var $this = $(this),
click = $.Deferred();
$this.one('click', function() { // click handler
click.resolve($this.text());
});
return click.then(getBookIds); // returns a promise for the ajax result
// after the link has been clicked
}).toArray();
$.when.apply($, promises).then(function fancyAjax() {
alert('alert message for fancy stuff');
});
(Demo)
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