问题描述:

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?

网友答案:

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)

相关阅读:
Top