用node的request模块批量下载图片


我想下载一些图片,图片在网站上是这样来存储的


 http://a.com/1.jpg
http://a.com/2.jpg
http://a.com/3.jpg

我的代码如下:


 var request = require('request');
var fs = require('fs');
var mkdir = require('mkdirp');

var preUrl = 'http://a.com/';
var dir = './images';

mkdir(dir, function(err) {
if(err) {
    console.log(err);
}
});
for(var i = 1; i <= 10; i++){
  var trueUrl = preUrl + i + '.jpg';
  var name = i + '.jpg';
   request(trueUrl, function(err, response, body) {
  if(!err && response.statusCode == 200) {
      download(trueUrl, dir, name);
      console.log("Done" + trueUrl);
                }
      });                
}
var download = function(url, dir, filename) {
request.head(url, function(err, res, body) {
    request(url).pipe(fs.createWriteStream(dir + '/' + filename));
});
};

但是发现下面的这一部分根本不会运行,即如果我在下面的代码上面输入console.log(111)的话就会循环输出111很多次,而下面的没有动静。。。


 request(trueUrl, function(err, response, body) {
      if(!err && response.statusCode == 200) {
          download(trueUrl, dir, name);
          console.log("Done" + trueUrl);
                    }
          });

我哪个地方出问题了?能指点一下吗?


等了等,基本上还是上面的代码,他一直会显示done http://a.com/10.jpg ....但是并没有下载下来。。并且电脑会特别卡

最后只是下载到了10.jpg

request node.js JavaScript

路过小王子 9 years, 4 months ago

for循环里面的异步回调中name变量是同一个值了。

おっぱい最高 answered 9 years, 4 months ago

在nodejs中for循环和回调嵌套就是灾难,因为普通运算会跳过回调直接执行,如果回调不够快请求基本上就等于如下代码:


 js


 var trueUrl;
var name;
for(var i = 1; i <= 10; i++){
  trueUrl = preUrl + i + '.jpg';
  name = i + '.jpg';         
}
request(trueUrl, function(err, response, body) {
  if(!err && response.statusCode == 200) {
      download(trueUrl, dir, name);
      console.log("Done" + trueUrl);
  }
});

所以应该换种方式进行操作。

  • 同步的request:[request-sync]
  • 使用数组
  • 把i++ 写到回调函数体内
  • 补充1:使用一个函数把request(url,function(err,response,body){})给封装进去,把trueUrl和name作为参数传进去(推荐);
  • 补充2:推荐使用nodegrass
acboy answered 9 years, 4 months ago

Your Answer