2015-04-17 21 views
5

Ho una promessa e voglio che si risolva solo quando la promessa interiore si è risolta. In questo momento si risolve prima che la funzione "risoluzione" sia stata raggiunta nel callback "loadend".promessa risolutiva prima della promessa interiore risolta

Cosa mi manca? Sono confuso dal modo in cui dovresti usare la risoluzione e da come puoi usare una promessa all'interno di un'altra promessa.

Non sono riuscito a trovare nulla che abbia aiutato sul web.

Nell'esempio seguente, fondamentalmente viene caricato un gruppo di file, per ogni file ottengo un blob e voglio passare questo blob in un lettore di file.

Dopo che tutti i file sono stati passati al lettore di file, voglio passare alla funzione successiva nella catena delle promesse.

In questo momento passa alla funzione successiva della catena senza attendere che venga risolta la risoluzione.

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

risposta

18

quando non return qualsiasi cosa, da then callback, esso assume il sincronismo e va a risolvere la promessa risultato con il risultato (undefined) immediatamente.

È necessario return una promessa da ogni funzione asincrona, tra cui then callback che si desidera ottenere incatenato.

In particolare, il codice dovrebbe diventare

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, meglio ancora, 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

ho avuto due funzioni che sia restituito un promessa che si era annidata promesse, (grazie al design del modulo) e alla fine delle promesse nidificate, ho chiamato la risoluzione della promessa contenuta, ma ho sentito che era sbagliato. Ma grazie al tuo esempio, sono stato in grado di abbandonare la promessa contenuta, e ho appena restituito la catena della promessa nidificata. Questo ha reso il mio codice molto più piacevole da leggere. Volevo solo darti i tuoi complimenti per quello. – WORMSS

Problemi correlati