Promesse de résolution avant que la promesse intérieure soit résolue

J'ai une promesse et je ne veux que résoudre si la promesse intérieure a résolu. À l'heure actuelle, il résout avant que la fonction "résolution" ait été atteinte dans le rappel "loadend".

Qu'est-ce qui me manque? Je suis confus quant à la façon dont vous êtes censé utiliser la résolution et à propos de la façon dont vous pouvez utiliser une promesse dans le cadre d'une autre promesse.

Je ne pouvais rien trouver sur le Web.

Dans l'exemple suivant, je charge essentiellement un tas de fichiers, pour chaque fichier, je reçois un blob et je souhaite passer ce blob dans un lecteur de fichiers.

Une fois que tous les fichiers ont été transmis au lecteur de fichiers, je souhaite passer à la fonction suivante dans la chaîne de promesses.

À l'heure actuelle, il passe à la fonction suivante de la chaîne sans attendre que la résolution soit appelée.

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

Lorsque vous ne return rien à partir des rappels, cela suppose une opération synchrone et permet de résoudre immédiatement les résultats obtenus avec le résultat ( undefined ).

Vous devez return une promesse de chaque fonction asynchrone , y compris les rappels que vous voulez faire enchaînés.

Plus précisément, votre code devrait devenir

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

Ou même mieux, aplatis :

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