2014-06-16 9 views
5

Ho questa classe:Chiama un metodo quando tutti i differiti sono completati?

(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)); 

La classe viene chiamato in un ciclo:

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

    }); 

La mia domanda è: esiste un modo per chiamare un metodo una volta che il ciclo è stato completato e self.fileRead è tornato è differito per tutto il ciclo?

Voglio chiamare il metodo anche se uno o più dei differiti fallisce.

+1

Non è quello che '.sempre()' è per? – DevlshOne

+1

È consigliabile utilizzare una libreria di promessa migliore. –

+0

'.read' usa metodi internamente sull'oggetto? C'è qualche ragione è un metodo di istanza? –

risposta

3

$ .quando consente di racchiudere più promesse in una sola. Altre librerie di promesse hanno qualcosa di simile. Costruire una serie di promesse restituiti da fileRead.read e quindi passare tale matrice a $ .quando e collegare poi/fatto/fallire/sempre metodi alla promessa restituito da .quando

// 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 tu mostri un esempio nel codice? – panthro

+0

ci sono esempi nei documenti e googling ti troverà di più ora che conosci il nome dell'api per usare http://api.jquery.com/jquery.when/ –

+0

Vuoi '$ .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 dice "quando tutte queste promesse saranno risolte ... fai qualcosa". Richiede un numero infinito (variabile) di parametri. In questo caso, hai una serie di promesse;

0

So che questo è chiuso, ma come dice il doc per $.when: Nel caso di più-Deferreds dove uno dei Deferreds viene respinto, jQuery.when immediatamente incendi le failCallbacks per il suo padrone differite. (l'enfasi immediatamente è mia)

Se si desidera completare tutti Differiti anche quando uno non riesce, credo che sia necessario trovare il proprio plugin lungo quelle linee di seguito. La funzione prevede una serie di funzioni che restituiscono un JQueryPromise.

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

Per soddisfare il requisito, "per chiamare il metodo, anche se uno o più dei differita fallisce" si vuole idealmente un metodo .allSettled() ma jQuery non ha quel particolare granello di zucchero, in modo da avere a che fare un lavoro fai da te:

si potrebbe trovare/scrivere un programma di utilità $.allSettled() o ottenere lo stesso effetto con una combinazione di .when() e .then() come segue:

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

se esistesse, $.allSettled() farebbe qualcosa di simile internamente.

successiva, "in myMethod, come distinguere le buone risposte dagli errori?", Ma questa è un'altra questione :)