2014-01-13 22 views
5

AJAXメソッドから約束を返すと、私はコードをより読みやすく/機能的にするためにどのように使用できるのか見て回っています。私の現在のシナリオは、getBookIdsという機能を持って、そのIDに基づいて書籍のタイトルを返すためにデータベースにAJAX呼び出しを発行することです。テーブルには5つの書籍があり、それぞれの書籍に対応するテキストプロパティを持つアンカータグがあります。すべてのアンカータグがクリックされたら、他のファンキーな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を使用するのではなく、約束の配列です。

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

言及する価値がある - 約束配列の集約は、jQueryの '$ .when'と、Bluebirdのようなより深刻な約束のライブラリの' Promise.all'で行われます。 –

+1

@Bergiこれをできるだけフレキシブルにするには、(このクラスのアンカータグで)jQuery配列を取り込み、それぞれに約束を作成し、各インデックスの状態をチェックして解決されましたか? – wootscootinboogie

+1

@wootscootinboogie:はい(私のコードでは 'map'のように)、いいえ、約束の状態を手動で確認する必要はありません。 Benjaminが述べたように、それらを集約するために['$ .when'](http://api.jquery.com/jQuery.when/)を使うことができます。 – Bergi

関連する問題