2015-09-10 2 views
5

Ich bin ein Formular-Validierung Aufbau und Versprechungen zu lernen, ich asynchrone Validierungsfunktionen versprechen Muster mit implementieren entschieden:Abort Ajax-Request in einem Versprechen

var validateAjax = function(value) { 
    return new Promise(function(resolve, reject) { 
     $.ajax('data.json', {data: {value: value}}).success(function(data, status, xhr) { 
      if (data.valid) { 
       resolve(xhr) 
      } 
      else { 
       reject(data.message) 
      } 
     }).error(function(xhr, textStatus) { 
      reject(textStatus) 
     }) 
    }) 
} 

//... 
var validators = [validateAjax]; 
$('body').delegate('.validate', 'keyup', function() { 
    var value = $('#the-input').val(); 
    var results = validators.map(function(validator) { 
     return validator(input) 
    }); 

    var allResolved = Promise.all(results).then(function() { 
     //... 
    }).catch(function() { 
     //... 
    }) 
}); 

Dies scheint zu funktionieren gut, wird die Eingabe validiert Benutzertypen (der Code wird vereinfacht, um nicht zu lang zu sein, z. B. Zeitüberschreitung, nachdem der Schlüssel fehlt usw.).

Jetzt frage ich mich, wie die Ajax-Anfrage zu beenden, wenn die Validierung aus dem vorherigen Keyup-Ereignis noch in Bearbeitung ist. Ist es irgendwie möglich zu erkennen, in welchem ​​Zustand die Verheißung ist und möglicherweise das Versprechen von außen abzulehnen?

Antwort

8

Promise Cancellation ist derzeit unter Spezifikation, es gibt keine eingebaute Möglichkeit, dies zu tun (es kommt aber). Wir implementieren können es uns:

var validateAjax = function(value) { 
    // remove explicit construction: http://stackoverflow.com/questions/23803743 
    var xhr = $.ajax('data.json', {data: {value: value}}); 
    var promise = Promise.resolve(xhr).then(function(data){ 
     if(!data.isValid) throw new Error(data.message); // throw errors 
     return data; 
    }); 
    promise.abort = function(){ 
     xhr.abort(); 
    }); 
    return promise; 
} 

Jetzt können wir töten die validateAjax fordert von abort auf das Versprechen Aufruf:

var p = validateAjax("..."); // make request 
p.abort(); // abort it; 
+0

Großartig, ich es, vielen Dank für Ihre Antwort. Anyway in Bezug auf die Entfernung von expliziten Konstruktion - die xhr muss immer noch von der validateAjax-Funktion zurückgegeben werden, oder? –

+0

Ihr validateAjax gibt undefined zurück - fehlt eine Zeile? –

+0

@LukasKral - Ich denke, die var 'Versprechen' müsste zurückgegeben werden, da es die' .abort' Funktion hat - aber ich habe den Code nicht geschrieben, also kann ich nur spekulieren –