在节点脚本中异步等待

时间:2020-04-20 17:44:09

标签: javascript node.js promise async-await async.js

我正在尝试执行下载某些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个网址,然后退出,而“ All done”消息从未显示。似乎以某种方式,即使正在等待,函数(queue.drain())返回的promise也从未解决。我想念什么?

我也尝试过:

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

在get_urls函数内部,但它不会更改任何内容,也不会执行其中的代码。

1 个答案:

答案 0 :(得分:-1)

希望对您有帮助。

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);
  })

更正目标和要写入文件的名称。

正如@Bergi所说,请阅读this以获取更多信息。