Загрузите файл из Интернета, используя Node js и loop

1

Я хочу загрузить несколько файлов из Интернета, используя этот код:

    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. Результатом, который я получаю, является всего лишь 1 файл с именем файла filename5.jar (или последним значением я var в цикле). Что я делаю неправильно?

  • 1
    Ваш запрос асинхронный, и он будет выполняться только после того, как ваш цикл завершится, следовательно, 5 из имени файла.
  • 0
    Я так и подозревал. Благодарю. Что я могу сделать, чтобы это работало?
Показать ещё 3 комментария
Теги:

2 ответа

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)
}
  • 0
    Спасибо, ваш код делает 5 отдельных файлов. У меня сейчас проблема в том, что все данные отправляются только в 1 случайный файл, остальные - пустые. Может ли быть так, что функция выполняется слишком быстро? Я попробовал setTimeout без особой удачи.
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);
}); 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню