2016-06-16 14 views
0

Ich habe ein Skript, das alle Bilder URL aus der Datenbank und laden Sie diese Bilder durch Request-Modul. Das Problem ist, dass wenn ich mehr als 400 Bilder habe, der Prozess über 480 stoppt und nicht weiter geht. Das Problem ist nicht die URL, weil irgendwann über 450 oder 467 zu stoppen ...herunterladen Bilder mit node.js Anfrage

var process = { 
      error: 0, 
      success: 0, 
      getTotal: function() { 
       return this.error + this.success; 
      } 
     }; 

     var request = require('request'); 
     var maxLength = 10 // 10mb 

     var callback = function(error, success) { 
      if (error) { 
       ++process.error; 
      } else { 
       ++process.success; 
      } 

      console.log(process.getTotal()); 

     }; 

     Photo.find({limit: 500}).exec(function (err, images){ 
      if (err || images.length === 0) { 
       return err; 
      } 

      for (var image in images) { 

       request({ 
        url: images[image].url, 
        encoding: null 
       }, function(err, res, body) { 
        //console.log(file.url); 
        if (err) { 
         return callback(res, null); 
        } 

        if (res.headers['content-length'] > maxLength*1024*1024) { 
         return callback(new Error('Image too large.'), null) 
        } 

        if (!~[200, 304].indexOf(res.statusCode)) { 
         return callback(new Error('Received an invalid status code.'), null); 
        } 

        if (!res.headers['content-type'].match(/image/)) { 
         return callback(new Error('Not an image.'), null); 
        } 

        callback(false, true); 
       }); 
      } 
     }); 

Auch habe ich mit einem Limit 5000 Bilder und der Prozessstopp 4800. getestet

+0

Das Problem ist, dass auf dem 'for' Block, Sie die' request() '-Funktion oft ausführen. Dein Code versucht also, alle diese Bilder gleichzeitig zu verarbeiten. Könnte ich vorschlagen, einige Versprechen Bibliothek, wie [Bluebird] (https://github.com/petkaantonov/bluebird). –

+0

Ich habe das folgende Modul testen: https://www.npmjs.com/package/then-request das hat Anfrage mit Versprechen und passiert das gleiche. Ich habe vergessen zu sagen, dass ich Segel js verwende und dies mit der Segelkonsole als Dienst läuft. –

+0

Sie können immer noch Bluebird verwenden, die 'map()' Funktion wird helfen, speziell mit der 'Nebenläufigkeit'-Option. Auf diese Weise stellen Sie sicher, dass Sie "x" Bilder gleichzeitig verarbeiten. –

Antwort

0

Wie wäre es etwa so aus:

var myConcurrency = 200; 
var promises = []; 

/** 
* @returns {Promise} 
*/ 
var getImage = function(image) { 
    return new Promise(resolve, reject) { 
     request({ 
      //... 
     }, function(err, res) { 
      if (err) reject(err); 
      return resolve(res); 
     }) 
    } 
} 

var callback = function() {}; 

/** 
* @returns {Promise} 
*/ 
var handleImage = function(res) { 

    if (res.headers['content-length'] > maxLength*1024*1024) { 
     return callback(new Error('Image too large.'), null) 
    } 

    if (!~[200, 304].indexOf(res.statusCode)) { 
     return callback(new Error('Received an invalid status code.'), null); 
    } 

    if (!res.headers['content-type'].match(/image/)) { 
     return callback(new Error('Not an image.'), null); 
    } 

} 

Photo.find({limit: 500}).exec(function (err, images){ 
    if (err || images.length === 0) { 
     return err; 
    } 
    Promise 
     .map(images, function() { 
      return getImage(); 
     }) 
     .map(handleImage, {concurrency: myConcurrency}); 

}); 
+0

Es ist dasselbe passiert. Ich habe beschlossen, ein Ergebnis auf die Abfrage zu nehmen. Also, auf diese Weise entferne ich die Schleife. –