Asyn c ждут в скрипте узла - PullRequest
       23

Asyn c ждут в скрипте узла

0 голосов
/ 20 апреля 2020

Я пытаюсь выполнить скрипт узла, который загружает некоторые URL. Выглядит это так:

const https = require('https');
const fs = require('fs');
const async = require('async');

function download_cb(err) {
    if (err) {
        console.log("Download error:"+err);
    }
}

function download_file(task) {
    const url = task.url;
    const dest = task.dest;
    var file = fs.createWriteStream(dest);
    var request = https.get(url, function(response) {
      response.pipe(file);
      file.on('finish', function() {
        file.close(download_cb);  // close() is async, call cb after close completes.
      });
    }).on('error', function(err) { // Handle errors
      fs.unlink(dest); // Delete the file async. (But we don't check the result)
      download_cb(err.message);
    });
  };

function get_urls() { 
  var queue = async.queue(download_file, 10);
  const urls = []; // some array of urls
  for (var i=0; i<urls.length; i++) {
    queue.push({url: urls[i], dest: dest/*whatever*/});
  }
  return queue.drain();
}

(async () {
    await get_urls().then(()=>{
        console.log("All done");
    })
  })();

Это завершает загрузку только первых 10 URL-адресов и затем завершается, в то время как сообщение «Все выполнено» никогда не отображается. Почему-то кажется, что обещание, возвращаемое функцией (queue.drain ()), никогда не разрешается, даже если его ожидают. Чего мне не хватает?

Я также пытался:

        queue.drain = function() {
            console.log("All files are downloaded");
        };

внутри функции get_urls, но это ничего не меняет, и код в ней тоже не выполняется.

1 Ответ

0 голосов
/ 20 апреля 2020

Надеюсь, это вам поможет.

const https = require('https');
const fs = require('fs');

function download_cb(err) {
  if (err) {
    console.log("Download error:" + err);
  }
}

function download_file(task) {
  return new Promise((resolve, reject) => {
    const url = task.url;
    const dest = task.dest;
    var file = fs.createWriteStream(dest);
    https.get(url, function (response) {
      response.pipe(file);
      file
        .on('finish', function () {
          file.close(download_cb);  // close() is async, call cb after close completes.
          resolve();
        });
    })
      .on('error', function (err) { // Handle errors
        fs.unlink(dest); // Delete the file async. (But we don't check the result)
        download_cb(err.message);
        reject();
      });
  })
};

async function get_urls(urls, dest) {
  for (var i = 0; i < urls.length; i++) {
    await download_file({ url: urls[i], dest: dest + 'filename-' + i/*whatever*/ });
  }
}

let urls = [
  'https://jwt.io/img/11.svg',
  'https://jwt.io/img/12.svg',
  'https://jwt.io/img/13.svg',
  'https://jwt.io/img/14.svg',
]

get_urls(urls, './')
  .then(() => {
    console.log("All done");
  })
  .catch(err => {
    console.log(err);
  })

Исправьте dest и имя файла для записи.

Как прокомментировал @Bergi, прочитайте this для больше информации.

...