返回Promise以便在点击处理程序中使用

时间:2014-01-13 21:26:36

标签: javascript jquery ajax promise

我正在使用AJAX方法返回promises,并了解如何使用它们来使我的代码更容易阅读/运行。我目前的情况是有一个函数getBookIds,它向数据库发出一个AJAX调用,根据它的ID返回一本书的标题。表中有五本书和一个锚标签,其文本属性对应于每本书。一旦点击所有锚标签,我想要一些其他花哨的AJAX方法。这是我到目前为止所得到的:

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');
     }
 }

这是一个人为的例子,但我很难看到如何将这些承诺融入我的日常工作中。这首先是利用承诺/延期的力量的一个坏榜样吗?似乎不是AJAX上的success回调,而是我已经在done内汇总了我的所有逻辑。有关更好地解决这个问题的任何建议吗?

1 个答案:

答案 0 :(得分:4)

  

我希望在点击所有锚标签后触发其他一些奇特的AJAX方法。

听起来您希望获得每次点击的承诺,然后您可以将其合并为所有点击的承诺。关键不是使用全局booksArray,而是使用一系列承诺。

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