2016-03-29 24 views
0

Ich versuche ein verzögertes Versprechen zu lösen, nachdem eine Q.allSettled beendet ist. Die .then der allSettled wird jedoch nie ausgeführt und die Array-Ergebnisse werden nicht zurückgegeben. Keine Ausnahmen werden geworfen Ich komme einfach nie in den .then Block. Wie Sie aus dem folgenden Code sehen können, bin ich in einem .then Block, der über einige Datei-Upload-Elemente iteriert und dann Datei-Uploads und einige Saves basierend auf diesen Returns ausführt.Q.allSettled gibt keine Versprechensergebnisse zurück

var deferred = Q.defer(); 

datacontext.getFileNameGuid(fileNamesNeeded).then(function (data) {     
    _.each($fileUploads, function(item){ 
     if (item.files.length > 0) { 
      var promise = uploadFile(item, data[remainingFilesToUpload]) 
       .then(function() { 
        return datacontext.saveItem(atom) 
         .then(function (data) { 
          return getItemSuccess(data, false); 
         }).done(); 
       }).catch(function (data) { 
        logger.logError("An error occurred while updating your item. Please try again.", data, 'Error', true);         
       }).done(); 

      fileUploadPromises.push(promise); 

      return promise; 
     } 
    }); 

    // Either execute promises or bail 
    if (fileUploadPromises.length > 0) { 
     // Handle blockUI and spinner in last then. 
     Q.allSettled(fileUploadPromises).then(function() { 
      deferred.resolve('Images have been saved and scheduled for thumbnail generation.'); 
     }); 
    } else { 
     // Other logic here 
    } 
}); 

return deferred.promise; 
+0

Vor allem vermeiden Sie die [latente antipattern] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

Auf welche der vielen "then" Callbacks kommst du nie? – Bergi

+0

Es gibt keinen Grund für irgendeinen dieser '.done()' Aufrufe – Bergi

Antwort

0

Nach Beratung von @Bergi Einnahme Refactoring ich ein paar Code, der die deferred antipattern wurde mit. Ich habe meinen Code in einen Q.fcall Block gepackt, um das Versprechen zurückzugeben und Q.allSettled in Q.all geändert. Unten ist der Endzustand meines Arbeitscodes.

HINWEIS: Es gibt Funktionsaufrufe zu Durandal spezifische Funktionalität und andere Funktionen, die ich weggelassen habe.

return Q.fcall(function() { 
    try { 

     var fileUploadPromises = []; 
     var $fileUploads = $(fileUploadClass); 
     var fileNamesNeeded = 0; 

     $fileUploads.each(function (index, item) { 
      if (item.files.length > 0) 
       fileNamesNeeded++; 
     }); 

     return datacontext.getFileNameGuid(fileNamesNeeded).then(function (data) { 
      _.each($fileUploads, function (item) { 
       if (item.files.length > 0) { 
        // Init upload file promise         
        var promise = uploadFile(item, data[remainingFilesToUpload]) 
         .then(function() { 
          return datacontext.saveItem(atom) 
           .then(function (data) { 
            return getItemSuccess(data, false); 
           }); 
         }).catch(function (data) {           
          logger.logError('An error occurred while updating your Item. Please try again.', data, 'Error', true); 
          app.trigger(config.publishedMessageNames.AtomFileUploaded, ""); 
         }); 

        fileUploadPromises.push(promise); 

        remainingFilesToUpload++; 
       } 
      }); 

      // Either execute promises or bail 
      if (fileUploadPromises.length > 0) {        
       return Q.all(fileUploadPromises) 
       .then(function (results) {         
        return datacontext.scheduleBatchTask(filesToUpload(), item.DocumentId()).then(function() { 
         app.trigger(config.publishedMessageNames.FileUploaded, data); 
        }); 
       }).done(); 
      } else { 
       app.trigger(config.publishedMessageNames.FileUploaded, ""); 
      } 
     });     
    } catch (e) { 
     return new Error(e); 
    } 
});