2016-06-16 7 views
0

データベースからすべての画像のURLを取得し、これらの画像をリクエストモジュールを通してダウンロードするスクリプトがあります。問題は、400以上の画像がある場合、プロセスは480以上で終了しないということです。いつか450または467上で停止しているため問題は node.jsリクエストで画像をダウンロード

...

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); 
       }); 
      } 
     }); 
URLではありません。また、私は限界5000個のイメージとこのようなことについてどのように4800

+0

問題は、 'for'ブロックで何度も' request() '関数を実行していることです。したがって、あなたのコードは、同時にこれらすべての画像を処理しようとしています。 [Bluebird](https://github.com/petkaantonov/bluebird)などの約束ライブラリを使用することをお勧めします。 –

+0

私は以下のモジュールをテストしています: https://www.npmjs.com/package/then-request これは約束で要求があり、同じことが起こりました。私は帆jsを使っていると言っていることを忘れていました。そして、これは帆のコンソールをサービスとして実行しています。 –

+0

Bluebirdを使用することができます。 'map()'関数は、特に 'concurrency'オプションを使用する際に役立ちます。そうすれば、一度に 'x '個のイメージを処理していることを確認できます。 –

答えて

0

オーバープロセスの停止でテストしています:

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

同じことが起こった。私は、クエリで1つの結果を取ることにしました。だから、この方法でループを削除します。 –

関連する問題