关于节点/ JS请求包的请求结束的问题

时间:2018-09-09 00:25:06

标签: node.js promise request

我试图了解.on('end',...)在节点包请求中的作用。

我的代码:

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

function downloadAsset(relativeAssetURL, fileName) {
  return new Promise((resolve, reject) => {
    try {
      let writeStream = fs.createWriteStream(fileName);
      var remoteImage = request(`https:${relativeAssetURL}`);
      remoteImage.on('data', function(chunk) {
        writeStream.write(chunk);
      });
      remoteImage.on('end', function() {
        let stats = fs.statSync(fileName);
        resolve({ fileName: fileName, stats: stats });
      });
    } catch (err) {
      reject(err);
    }
  });
}

我想做的是下载一个远程映像,获取一些文件统计信息,然后解决承诺,以便我的代码可以执行其他操作。

我发现的是,下载文件后,诺言并不总是能够解决;在那之前它可能会解决一点。我以为这就是.on('end',...)的目的。

完全下载图像后,如何解决此诺言?

1 个答案:

答案 0 :(得分:1)

the docs说:

  

writable.write()方法将一些数据写入流,并在数据被完全处理后调用提供的回调。

因此,writable.write()异步。仅仅因为您的上一个writeStream.write已被调用并不一定意味着所有写操作都已完成。您可能要调用.end方法,这意味着:

  

调用writable.end()方法表示没有更多数据将被写入Writable。可选的块和编码参数允许在关闭流之前立即写入最后一个额外的数据块。如果提供,则可选的回调函数将作为“ finish”事件的侦听器附加。

因此,请尝试在writeStream.end请求结束时调用remoteImage,并在编写完成后将回调传递给writeStream.end,该回调可解决Promise

function downloadAsset(relativeAssetURL, fileName) {
  return new Promise((resolve, reject) => {
    try {
      const writeStream = fs.createWriteStream(fileName);
      const remoteImage = request(`https:${relativeAssetURL}`);
      remoteImage.on('data', function(chunk) {
        writeStream.write(chunk);
      });
      remoteImage.on('end', function() {
        writeStream.end(() => {
          const stats = fs.statSync(fileName);
          resolve({ fileName: fileName, stats: stats });
        });
      });
    } catch (err) {
      reject(err);
    }
  });
}

(也请尽量不要混用varlet / const-在ES6 +环境中,最好使用const,它通常更易于阅读且问题更少,像吊装)