2014-06-16 5 views
5

Ich habe diese Klasse:Eine Methode aufrufen, wenn alle Deferred abgeschlossen sind?

(function(){ 
"use strict"; 

var FileRead = function() { 
    this.init(); 
}; 


p.read = function(file) { 

    var fileReader = new FileReader(); 
    var deferred = $.Deferred(); 

    fileReader.onload = function(event) { 
     deferred.resolve(event.target.result); 
    }; 

    fileReader.onerror = function() { 
     deferred.reject(this); 
    }; 

    fileReader.readAsDataURL(file); 

    return deferred.promise(); 

}; 

lx.FileRead = FileRead; 
}(window)); 

Die Klasse wird in einer Schleife aufgerufen:

var self = this; 
    $.each(files, function(index, file){ 
     self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);}); 

    }); 

Meine Frage ist, gibt es eine Möglichkeit, eine Methode aufrufen, sobald die Schleife und self.fileRead abgeschlossen ist zurückgekehrt es ist für alles in der Schleife aufgeschoben?

Ich möchte es die Methode aufrufen, auch wenn eine oder mehrere der zurückgestellten fehlschlägt.

+1

Ist das nicht was '.always()' für ist? – DevlshOne

+1

Sie sollten eine bessere Versprechen Bibliothek verwenden. –

+0

Verwendet '.read' intern irgendwelche Methoden für das Objekt? Gibt es einen Grund, dass es sich um eine Instanzmethode handelt? –

Antwort

3

$ .when können Sie mehrere Versprechen in einem zusammenfassen. Andere Versprechen Bibliotheken haben etwas ähnliches. Erstellen Sie eine Reihe von Versprechungen zurück von fileRead.read und dann das Array passieren zu $ ​​.when und Haken dann/done/Fail/immer Methoden, um die Versprechen zurück von .when

// use map instead of each and put that inside a $.when call 
    $.when.apply(null, $.map(files, function(index, file){ 
     // return the resulting promise 
     return self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);}); 

    }).done(function() { 

     //now everything is done 
    }) 
+1

Coudl Sie zeigen ein Beispiel im Code? – panthro

+0

Es gibt Beispiele in der Dokumentation und googling finden Sie jetzt mehr, dass Sie den Namen der API kennen, um zu verwenden http://api.jquery.com/jquery.when/ –

+0

Sie wollen '$ .when.apply (null, '... –

0
var self = this; 
var processFiles = function (data) { 
    var promises = []; 
    $.each(files, function (index, file) { 
     var def = data.fileRead.read(file); 
     promises.push(def); 
    }); 
    return $.when.apply(undefined, promises).promise(); 
} 

self.processFiles(self).done(function(results){ 
    //do stuff 
}); 

$.when sagt "Wenn all diese Versprechen gelöst sind ... tu etwas". Es benötigt eine unendliche (variable) Anzahl von Parametern. In diesem Fall haben Sie eine Reihe von Versprechen;

0

Ich weiß, das geschlossen ist, aber wie die doc Staaten für $.when: Im Mehr Deferreds Fall, in dem einer der Deferreds abgelehnt wird, jQuery.when sofort Feuer die failCallbacks für seine Master Latente. (Betonung auf sofort gehört mir)

Wenn Sie abschließen möchten alle Zurückgestellt, auch wenn einer fehlschlägt, ich glaube, Sie müssen mit Ihrem eigenen Plugin in diesen Zeilen unten kommen. Die $.whenComplete Funktion erwartet ein Array von Funktionen, die eine JQueryPromise zurückgeben.

var whenComplete = function (promiseFns) { 
     var me = this; 
     return $.Deferred(function (dfd) { 
      if (promiseFns.length === 0) { 
       dfd.resolve([]); 
      } else { 
       var numPromises = promiseFns.length; 
       var failed = false; 
       var args; 
       var resolves = []; 

       promiseFns.forEach(function (promiseFn) { 
        try { 
         promiseFn().fail(function() { 
          failed = true; 
          args = arguments; 
         }).done(function() { 
          resolves.push(arguments); 
         }).always(function() { 
          if (--numPromises === 0) { 
           if (failed) { 
            //Reject with the last error 
            dfd.reject.apply(me, args); 
           } else { 
            dfd.resolve(resolves); 
           } 
          } 
         }); 
        } catch (e) { 
         var msg = 'Unexpected error processing promise. ' + e.message; 
         console.error('APP> ' + msg, promiseFn); 
         dfd.reject.call(me, msg, promiseFn); 
        } 
       }); 
      } 
     }).promise(); 
    }; 
0

die Anforderung zu adressieren „die Methode aufzurufen, selbst wenn ein oder mehrere der latenten versagt“ Sie idealerweise eine .allSettled() Methode wollen, aber jQuery nicht über diese bestimmte Getreide Zucker, so dass Sie zu tun haben, ein DIY Job:

Sie finden konnten/schreiben $.allSettled() Dienstprogramm oder die gleiche Wirkung mit einer Kombination aus .when() und .then() erreichen wie folgt:

var self = this; 
$.when.apply(null, $.map(files, function(index, file) { 
    return self.fileRead.read(file).then(function(fileB64) { 
     self.fileShow(file, fileB64, fileTemplate); 
     return fileB64;//or similar 
    }, function() { 
     return $.when();//or similar 
    }); 
})).done(myMethod); 

Wenn es existiert, $.allSettled() würde intern etwas Ähnliches tun.

Next "in myMethod, wie die guten Antworten von den Fehlern zu unterscheiden?", Aber das ist eine andere Frage :)