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

woo*_*gie 5 javascript ajax jquery 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>
Run Code Online (Sandbox Code Playgroud)

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');
     }
 }
Run Code Online (Sandbox Code Playgroud)

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

Ber*_*rgi 6

我想要一些其他花哨的 AJAX 方法在所有锚标记都被点击后触发。

这听起来像是您希望为每次点击获得一个承诺,然后您可以将其合并为所有点击的承诺。重点不是使用 global booksArray,而是使用 promise 数组。

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');
});
Run Code Online (Sandbox Code Playgroud)

演示

  • @wootscootinboogie: [`.one()`](http://api.jquery.com/one/) 只执行一次处理程序,即在不再需要时(当承诺已经履行时)它会自动解除绑定 (2认同)
  • @JohnS:不,没有缺陷。不是返回点击时解析的 `click` 延迟,而是返回由 `then` 构建的承诺 - 将 ajax 函数*链接*到解析中。这些结果承诺与 ajax 响应一起解决。感谢您的小提琴,我已经用我的代码更新了它并包含了一些日志记录:http://jsfiddle.net/Q7qh7/1/! (2认同)