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

이 또한 내가 제한 5000 개 이미지와 4800

+0

문제는 'for'블록에서 여러 번 'request()'함수를 실행하고 있다는 것입니다. 따라서 귀하의 코드는 모든 이미지를 동시에 처리하려고합니다. [Bluebird] (https://github.com/petkaantonov/bluebird)와 같은 일부 약속 라이브러리를 사용하는 것이 좋습니다. –

+0

나는 다음 모듈을 시험해 본다. https://www.npmjs.com/package/then-request 이것은 약속과 함께 요청을 받았으며 그와 같은 일이 일어났다. 나는 돛 js를 사용하고 있으며이 돛을 서비스로 사용한다고 말하기를 깜박했습니다. –

+0

Bluebird를 계속 사용할 수 있습니다. 특히'concurrency' 옵션을 사용하는'map()'함수가 도움이 될 것입니다. 그렇게하면 한 번에'x '개의 이미지를 처리 ​​할 수 ​​있습니다. –

답변

0

을 통해 프로세스 중지와 함께 테스트 한 ... URL이 아닌 어떻게 이런 일에 대해 :

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

같은 일이 일어났습니다. 나는 쿼리에 대해 하나의 결과를 가져 가기로 결정했다. 그래서이 방법으로 루프를 제거합니다. –

관련 문제