title: How and When to generate thumbnail in node.js?
body: <p>So here is how my app handle image uploading and generate thumbnail</p>
  
  <pre><code>router.post('/upload', saveupload, generateThumb, saveDB)
  
  function generateThumb (req, res, next){
  
      var filePath = req.files.file.path;
      var fileDir = req.files.file.dir;
      var filename = req.files.file.name;
  
      async.series({
          noProfile:function(callback){
              gm(filePath)
                  .noProfile()
                  .write(filePath, function(err){
                      callback(err);
                  })
          },
          large:function(callback){
              var thumb_width = config.thumb.lg.width;
              var thumb_height = config.thumb.lg.height;
              var quality = config.thumb.lg.quality;
              var thumbName = filename.split('.')[0]+'_thumb_'+thumb_width+'x'+thumb_height+'.'+filename.split('.')[1];
              var thumbPath = path.join(fileDir, thumbName);
              gm(filePath)
                  .noProfile()
                  .resize(thumb_width, thumb_height)
                  .quality(quality)
                  .write(thumbPath, function(err){
                      callback(err)
                  })
          },
          middle:function(callback){
              var thumb_width = config.thumb.md.width;
              var thumb_height = config.thumb.md.height;
              var quality = config.thumb.md.quality;
              var thumbName = filename.split('.')[0]+'_thumb_'+thumb_width+'x'+thumb_height+'.'+filename.split('.')[1];
              var thumbPath = path.join(fileDir, thumbName);
              gm(filePath)
                  .noProfile()
                  .resize(thumb_width, thumb_height)
                  .quality(quality)
                  .write(thumbPath, function(err){
                      callback(err)
                  })
          },
          small:function(callback){
              var thumb_width = config.thumb.sm.width;
              var thumb_height = config.thumb.sm.height;
              var quality = config.thumb.sm.quality;
              var thumbName = filename.split('.')[0]+'_thumb_'+thumb_width+'x'+thumb_height+'.'+filename.split('.')[1];
              var thumbPath = path.join(fileDir, thumbName);
              gm(filePath)
                  .noProfile()
                  .resize(thumb_width, thumb_height)
                  .quality(quality)
                  .write(thumbPath, function(err){
                      callback(err)
                  })
          }},
          function(err, obj){
              if(err){
                  return next(err)
              }
  
              next()
          })
  }
  </code></pre>
  
  <p>the code work well, util now I find some problem:</p>
  
  <p><strong>1:generate thumbnail this way slows the uploading speed</strong></p>
  
  <p>for every picture user uploaded, I need to generate 3 thumbnails , large, middle, small, I first save the uploaded picture to disk then pick up the picture in gm to crop metadata and generate thumbnail, this method really slow down the uploading speed, new upload can not start util the previous thumbnail is generated. what I want is keep the thumbnail generation out of the request route, so I can maintain max upload speed. any idea how?</p>
  
  <p><strong>2:Is there a better way to batch generate thumbnail</strong></p>
  
  <p>As you can see, I need 3 thumbnail, I did not see any document of gm on how to batch generate thumbnail, but I think there has to be a better way.</p>