2014-01-13 1 views
5

Ich spiele herum mit Versprechen von einer AJAX-Methode und sehen, wie ich sie verwenden kann, um meinen Code einfacher zu lesen/funktional. Mein aktuelles Szenario ist eine Funktion getBookIds, die einen AJAX-Aufruf an eine Datenbank ausgibt, um den Titel eines Buches basierend auf seiner ID zurückzugeben. Es gibt fünf Bücher in der Tabelle und ein Anker-Tag, dessen Texteigenschaften jedem Buch entsprechen. Ich möchte, dass eine andere fantastische AJAX-Methode ausgelöst wird, nachdem alle Anker-Tags angeklickt wurden. Hier ist, was ich bisher habe:Returning Promises für die Verwendung in Click-Handlern

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

Dies ist ein konstruiertes Beispiel, aber ich bin zu kämpfen, um zu sehen, wie ich diese Versprechen in meine tägliche Arbeit integrieren können. Ist das nur ein schlechtes Beispiel dafür, die Macht von Versprechen/Aufschubs zu nutzen? Es scheint, dass anstelle der success Rückruf auf AJAX, nicht habe ich meine ganze Logik aufgerollt innerhalb done. Irgendwelche Vorschläge, um das besser in Angriff zu nehmen?

+1

Gute Frage, aber es gehört in: http://codereview.stackexchange.com/ –

+1

@JohnStrickler nicht jede Frage mit Code gehört in Codereview. Er fragt nach einem Konzept und der Code ist ein Beispiel, kein Produktionscode. Diese Frage ist Thema hier und es ist nicht einmal eine schlechte :) –

+1

@JohnStrickler Ich poste dort auch, ich bin froh, es zu haben, wohin es am passendsten ist. – wootscootinboogie

Antwort

4

Ich möchte eine andere ausgefallene AJAX-Methode auslösen, nachdem alle Anker-Tags angeklickt wurden.

Das klingt, als ob Sie ein Versprechen für jeden Klick erhalten möchten, den Sie dann zu einem Versprechen für alle Klicks kombinieren können. Der Punkt ist nicht, eine globale booksArray, sondern eine Reihe von Versprechen zu verwenden.

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

Erwähnenswert - die Aggregation eines Versprechens-Arrays erfolgt mit '$ .when' in jQuery und mit' Promise.all' in seriöseren Bibliotheken wie Bluebird. –

+1

@Bergi Wenn ich dies so flexibel wie möglich machen würde, würde ich eine Funktion benötigen, die ein jQuery-Array (in dieser Klasse anchor-Tags) aufnimmt und für jedes ein Versprechen erstellt und dann den Status jedes Index überprüft, um zu sehen, ob sie sind aufgelöst? – wootscootinboogie

+1

@wootscootinboogie: Ja (wie die 'map' in meinem Beispielcode tut) und Nein, Sie müssen die Zusicherungszustände nicht manuell überprüfen. Wie Benjamin bereits erwähnt hat, können Sie ['$ .when'] (http://api.jquery.com/jQuery.when/) verwenden, um sie zu aggregieren. – Bergi