promise de resolución antes de la promise interna resuelta

Tengo una promise y quiero que se resuelva solo cuando la promise interna se haya resuelto. En este momento se resuelve antes de que se haya alcanzado la function "resolver" en la callback "loadend".

¿Qué me estoy perdiendo? Estoy confundido sobre la forma en que se supone que debes usar la resolución y sobre cómo puedes usar una promise dentro de otra promise.

No pude encontrar nada que ayudara en la web.

En el siguiente ejemplo, básicamente cargo un montón de files, para cada file obtengo un blob y quiero pasar este blob en un lector de files.

Una vez que todos los files se han pasado al lector de files, quiero pasar a la siguiente function en la cadena de promises.

Ahora va a la siguiente function de la cadena sin esperar que se llame.

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

Cuando no return nada de las devoluciones de llamada, asume una operación síncrona y va a resolver la promise de resultado con el resultado ( undefined ) inmediatamente.

Debe return una promise de cada function asincrónica , incluidas las devoluciones de llamada que desea encadenar.

Específicamente, su código debería convertirse

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

o incluso mejor, aplanado :

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