【问题标题】:Download a file from web using Node js and loop使用 Node js 从 Web 下载文件并循环
【发布时间】:2018-07-16 11:42:42
【问题描述】:

我想使用此代码从网上下载多个文件:

    var fs = require('fs');
    var http = require('http');
    var request = require('request');

    var file;
    for(var i = 1; i <= 5; i++) {
         //CHECK IF REMOTE FILE EXISTS
         request('http://webaddress.com/filename' + i + '.jar', function (err, resp) {

         //IF EXISTS DO
         if (resp.statusCode == 200) {
             //DOWNLOAD DATA AND CREATE A NEW .JAR FILE
             file = fs.createWriteStream('D:\\filename' + i + '.jar');
             http.get('http://webaddress.com/filename' + i + '.jar', function(response) {
                  response.pipe(file);
                  file.on('finish', function() {
                      file.close();
                  });
             });
         }

         //FILE DOES NOT EXIST
         });
     }

我想要的结果是:用文件名filename1-5.jar下载了多个文件。我得到的结果只是一个文件名为 filename5.jar 的文件(或循环中 i var 的最后一个值)。我做错了什么?

【问题讨论】:

  • 你的请求是异步的,它只会在你的循环完成后执行,因此文件名中的5。
  • 我怀疑是这样。谢谢。我该怎么做才能让它发挥作用?
  • 看到这个答案,可以帮你解决问题stackoverflow.com/a/19911657/8221063
  • 谢谢@LucasDuarte,我会去看看。
  • @lupu51nfactumN778,我已经为你添加了答案。

标签: javascript node.js


【解决方案1】:

就像@Ionut 说你的请求是异步的,所以你需要等待它

let fs = require('fs');
let request = require('request');

let download = (uri, filename) => {
    return new Promise ((resolve, reject) => {
        request.head(uri, function(err, res) {

            if (res.statusCode === 200) {
                request(uri).pipe(fs.createWriteStream(filename)).on('close', resolve);
            } else {
                reject(res.statusCode);
            }
        });
    });
};

let promises = [];

for(let i = 1; i <= 5; i++) {
    promises.push(download('http://webaddress.com/filename' + i + '.jar', 'D:\\filename' + i + '.jar'));
}

Promise.all(promises).then(() => {
    process.exit(0);
}); 

【讨论】:

    【解决方案2】:

    你的请求是异步的,它只会在你的循环完成后执行,因此文件名中的5。一个解决方案是通过创建一个新函数并在循环内调用它来单独威胁您的代码:

    var fs = require('fs');
    var http = require('http');
    var request = require('request');
    
    var file;
    
    function customRequest(i){
    
      //CHECK IF REMOTE FILE EXISTS
      return request('http://webaddress.com/filename' + i + '.jar', function(err, resp) {
    
        //IF EXISTS DO
        if (resp.statusCode == 200) {
          //DOWNLOAD DATA AND CREATE A NEW .JAR FILE
          file = fs.createWriteStream('D:\\filename' + i + '.jar');
          http.get('http://webaddress.com/filename' + i + '.jar', function(response) {
            response.pipe(file);
            file.on('finish', function() {
              file.close();
            });
          });
        }
    
        //FILE DOES NOT EXIST
      });
    
    }
    
    for (var i = 1; i <= 5; i++) {
       customRequest(i)
    }
    

    【讨论】:

    • 谢谢,您的代码确实生成了 5 个单独的文件。我现在遇到的问题是所有数据都只进入 1 个随机文件,其他的都是空的。这可能是函数执行得太快了吗?我尝试了 setTimeout,但运气不佳。
    猜你喜欢
    • 2017-01-12
    • 1970-01-01
    • 2020-09-27
    • 2020-02-24
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 2018-09-20
    • 2020-05-08
    相关资源
    最近更新 更多