2015-04-17 18 views
5

Ich habe ein Versprechen, und ich will es nur lösen, wenn innere Versprechen gelöst hat. Momentan löst es auf, bevor die "resolve" -Funktion im "loadend" -Rückruf erreicht wurde.Versprechen lösen, bevor inneres Versprechen gelöst

Was fehlt mir? Ich bin verwirrt über die Art, wie du Entschlossenheit verwenden sollst und darüber, wie du ein Versprechen in einem anderen Versprechen verwenden kannst.

Ich konnte nichts finden, das im Web geholfen hat.

Im folgenden Beispiel lade ich grundsätzlich eine Reihe von Dateien, für jede Datei bekomme ich einen Blob und ich möchte diesen Blob in einem Dateireader übergeben.

Sobald alle Dateien an den Dateireader übergeben wurden, möchte ich zur nächsten Funktion in der Versprechungskette übergehen.

Jetzt geht es zur nächsten Funktion in der Kette, ohne darauf warten zu müssen, dass die Auflösung aufgerufen wird.

var list = []; 
var urls = this.files; 

urls.forEach(function(url, i) { 
    list.push(
     fetch(url).then(function(response) { 
      response.blob().then(function(buffer) { 

       var promise = new Promise(
        function(resolve) { 

         var myReader = new FileReader(); 
         myReader.addEventListener('loadend', function(e) { 
          // some time consuming operations 
          ... 
          window.console.log('yo'); 
          resolve('yo'); 
         }); 

         //start the reading process. 
         myReader.readAsArrayBuffer(buffer); 
        }); 

       promise.then(function() { 
        window.console.log('smooth'); 
        return 'smooth'; 
       }); 

      }); 
     }) 
    ); 
}); 

... 

// run the promise... 
Promise 
    .all(list) 
    .then(function(message){ 
     window.console.log('so what...?'); 
    }) 
    .catch(function(error) { 
     window.console.log(error); 
    }); 

Antwort

18

Wenn Sie von then Rückrufe nicht return alles tun, nimmt es einen synchronen Betrieb und geht das Ergebnis Versprechen mit dem Ergebnis (undefined) sofort zu lösen.

Sie müssen return ein Versprechen von jeder asynchronen Funktion, einschließlich then Rückrufe, die Sie wollen gekettet werden.

Insbesondere sollten Sie Ihren Code

var list = this.files.map(function(url, i) { 
//     ^^^^ easier than [] + forEach + push 
    return fetch(url).then(function(response) { 
     return response.blob().then(function(buffer) { 
      return new Promise(function(resolve) { 
       var myReader = new FileReader(); 
       myReader.addEventListener('loadend', function(e) { 
        … 
        resolve('yo'); 
       }); 
       myReader.readAsArrayBuffer(buffer); 
      }).then(function() { 
       window.console.log('smooth'); 
       return 'smooth'; 
      }); 
     }) 
    }); 
}); 

werden oder noch besser, flattened:

var list = this.files.map(function(url, i) { 
    return fetch(url).then(function(response) { 
     return response.blob(); 
    }).then(function(buffer) { 
     return new Promise(function(resolve) { 
      var myReader = new FileReader(); 
      myReader.addEventListener('loadend', function(e) { 
       … 
       resolve('yo'); 
      }); 
      myReader.readAsArrayBuffer(buffer); 
     }); 
    }).then(function() { 
     window.console.log('smooth'); 
     return 'smooth'; 
    }); 
}); 
+0

Ich hatte zwei Funktionen, die beide ein Versprechen zurück, das Versprechen eingenistet hatten, (aufgrund der Modulbauweise) und Am Ende der verschachtelten Versprechen nannte ich die Entschlossenheit des enthaltenen Versprechens, fühlte aber, dass dies falsch war. Aber dank Ihres Beispiels konnte ich das enthaltene Versprechen ablegen und habe nur die Kette der geschachtelten Versprechen zurückgegeben. Das machte meinen Code viel besser zu lesen. Ich wollte dir nur Daumen dafür geben. – WORMSS

Verwandte Themen