2015-12-23 12 views

risposta

4

È possibile utilizzare di Promise.mapSeries Bluebird:

var files = [ 
    'file1', 
    'file2' 
]; 

var result = Promise.mapSeries(files, function(file) { 
    return downloadFile(file); // << the return must be a promise 
}); 

A seconda di quello che si utilizza per scaricare il file, potrebbe essere necessario costruire una promessa o no.

Aggiornamento 1

Un esempio di una funzione downloadFile() utilizzando solo nodejs:

var http = require('http'); 
var path = require('path'); 
var fs = require('fs'); 

function downloadFile(file) { 
    console.time('downloaded in'); 
    var name = path.basename(file); 

    return new Promise(function (resolve, reject) { 
     http.get(file, function (res) { 
      res.on('data', function (chunk) { 
       fs.appendFileSync(name, chunk); 
      }); 

      res.on('end', function() { 
       console.timeEnd('downloaded in'); 
       resolve(name); 
      }); 
     }); 
    }); 
} 

Aggiornamento 2

Come suggerito Gorgi Kosev, la costruzione di una catena di promesse utilizzando un ciclo funziona anche:

var p = Promise.resolve(); 
files.forEach(function(file) { 
    p = p.then(downloadFile.bind(null, file)); 
}); 

p.then(_ => console.log('done')); 

Una catena di promesse ti porterà solo il risultato dell'ultima promessa della catena mentre mapSeries() ti offre un array con il risultato di ogni promessa.

+0

Senza mapSeries: 'var downloads = []; per (var p = Promise.pending(), i = 0; i downloadFile (files [i]))); return Promise.all (download) ' –

+0

@GorgiKosev Il tuo codice non funziona ma sì, costruendo una catena di anche le promesse funzionerebbero, ma usare 'Promise.all()' qui è sbagliato, stai facendo un 'Promise.all ([p, p, p])', ogni file verrà scaricato più volte. Aggiornerò la mia risposta con il tuo suggerimento – Shanoor

+0

No, questo non è corretto. Una promessa rappresenta un'operazione che è già stata avviata e tentare di collegarla più volte non farà ripetere la stessa operazione. È del tutto normale usare "Promise.all" come se fosse giusto allegare più callback "allora" a una singola promessa. –

1

utilizzando Bluebird, c'è una situazione simile al tuo, con una risposta qui: How to chain a variable number of promises in Q, in order?

Questa sembra una soluzione decente, ma a mio parere molto meno leggibile ed elegante come async.eachSeries (So che hai detto te Non voglio la soluzione 'asincrona' ma forse puoi riconsiderare: