仅在下载完成后返回解析[http.get + Promise]

时间:2019-05-29 05:39:39

标签: node.js es6-promise downloading

下面是我的代码,我试图仅在文件下载完成时返回。但是,即使下载完成,请求也会挂起。

const download = async () => {
    await new Promise((resolve) => {
        let file = fs.createWriteStream('./20181221001417.zip');
        http.get('http://speedtest.ftp.otenet.gr/files/test100k.db', (response) => {
           response.pipe(file);
        });
        file.on('finish', () => resolve('hi'));
    });
}

任何建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

您的代码虽然可以正常工作:)。在这种情况下,writeStreamObject应该是包含要保存流数据的文件的路径的名称。 从您的代码看来,一旦将响应成功地传递到流中,您似乎想要压缩文件。

您可以将以下代码放入js文件中,并使用node.js执行它,它将把图像文件下载到zip目录中。之后,它会压缩该zip目录并将其命名为file.zip

  

Blockquote如果运行此代码段,请确保在该代码段将要驻留的当前目录中有一个zip目录。否则可能会出错。您可以选择添加路径,只需将路径添加到path.join中即可,例如path.join(__dirname, "your_path", "filename.extension")。有时扩展名也很重要,因此请当心!就我而言,我有一个要下载的jpeg文件,但在文件流对象中提供了.png扩展名,因此创建了损坏的图像。

const http = require('http');
const fs = require('fs');
const path = require('path');
const zipDir = require('zip-dir');


const download = async () => {
  return new Promise((resolve) => {
    let filePath = path.join(__dirname, 'zip', 'image.jpg');
    let writeStream = fs.createWriteStream(filePath);
    http.get('http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg', (response) => {
      response.pipe(file);
    });
    // on finish event resolve the promise
    writeStream.on('finish', resolve);
  });
}

function zipTheFile() {
  let zipPath = path.join(__dirname, "file.zip");
  let sourcePath = path.join(__dirname, "zip");
  return new Promise((resolve, reject) => {
    zipDir(sourcePath, {
      saveTo: zipPath
    }, function (err, buffer) {
      if (err) {
        return reject(err);
      }
      return resolve('done');
    });
  })
}

(async () => {
  await download().catch(err => console.log(err));
  await zipTheFile();
})();

我要使用zip-dir库压缩该文件夹的压缩

如果您想从浏览器下载文件,那就很简单了。在这种情况下,我们的想法是将上述逻辑放在FileDownloadService这样的服务中。 downloadAndZipFile在这里的功能完全相同,就像首先下载文件并将其压缩。然后,它创建一个ReadStream对象并将其通过管道传递到资源库中,从而使浏览器可以下载文件。

var express = require("express");
var router = express.Router();
var path = require('path');
var mime = require('mime');
var fs = require('fs');

router.get('/download', async function (req, res) {

  await FileDownloadService.downloadAndZipFile();

  var file = path.join(__dirname, "file.zip")
  var mimetype = mime.lookup(file);

  // the name for file to be saved
  const fileName = "myzipFile"

  res.setHeader('Content-disposition', 'attachment; filename=' + fileName);
  res.setHeader('Content-type', mimetype);

  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});
module.exports = router;