2014-01-13 40 views
5

我在回顧AJAX方法中的承諾並查看如何使用它們使我的代碼更易於閱讀/功能。我目前的場景是有一個函數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

大的問題,但它屬於:http://codereview.stackexchange.com/ –

+1

@JohnStrickler不是代碼的每一個問題屬於在代碼審查。他詢問一個概念,代碼是一個不是生產代碼的例子。這個問題是在這裏的主題,它甚至不是一個壞的:) –

+1

@JohnStrickler我在那裏發帖,我很高興將它遷移到最合適的地方。 – wootscootinboogie

回答

4

我想要一些其他花哨的AJAX方法來點擊所有錨點標籤。

這聽起來像是你想爲每次點擊得到承諾,然後你可以將它合併成一個承諾,以實現所有點擊。關鍵不在於使用全局的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'); 
}); 

Demo

+1

值得一提的是 - promise數組的聚合是通過jQuery中的'$ .when'完成的,而在Bluebird等更爲嚴格的承諾庫中使用'Promise.all'完成。 –

+1

@Bergi如果我要儘可能靈活,我需要一個函數,它接受一個jQuery數組(在這個類的錨標籤中),併爲每一個創建一個承諾,然後檢查每個索引的狀態以查看它們是否是解決? – wootscootinboogie

+1

@wootscootinboogie:是的(正如我的示例代碼中的'map')並且不,您不需要手動檢查承諾狀態。正如Benjamin所說,你可以使用['$ .when'](http://api.jquery.com/jQuery.when/)來聚合它們。 – Bergi