首页 > 解决方案 > 如何在多个管道写入流中正确使用 Promise

问题描述

var promisePipe = require("promisepipe");
var fs = require("fs");
var crypt = require("crypto");
var // ....


files = ['/mnt/Storage/test.txt', '/mnt/Storage/test2.txt', '/mnt/Storage/test3.txt']

var promises = files.map(function(file_enc) {
  return new Promise(function(resolve, reject) {
    var file_out = file_enc + '.locked';
    promisePipe(
      fs.createReadStream(file_enc),
      crypt.createCipheriv(alg, genhashsub, iv),
      fs.createWriteStream(file_out),
    ).then(function(streams){
      console.log('File written: ' + file_out);
      // Promise.resolve(file_out); // tried but doesnt seem to do anything
    }, function(err) {
      if(err.message.substring(0, 7) === 'EACCES:') {
        console.log('Error (file ' + file_out + '): Insufficient rights on file or folder');
      } else {
        console.log('Error (file ' + file_out + '): ' + err);
      }
      // Promise.reject(new Error(err)); // tried but doesnt seem to do anything

    });
  })
});

Promise.all(promises).then(final_function(argument));

我正在尝试加密包含在名为files.
为了简单起见,我在此示例中手动添加了它们。

我想要发生的事情:

  1. 创建promises数组以promises.all在完成时调用
  2. 遍历数组
    1. 为这个 IO 操作创建 Promise
    2. 读取文件\
    3. 加密文件——由于文件大(+3GB),全部使用流完成
    4. 写文件/
    5. 完成写入后,解决此 IO 操作的承诺
  3. 一旦所有承诺都解决(或拒绝),运行完成脚本

怎么了:

  1. 第一个文件的加密开始
  2. .then(final_function(argument))叫做
  3. 第一个文件的加密结束

这些文件都被正确加密,之后可以解密。
此外,还会显示错误以及写入确认。

我搜索了 Stack 和 Google,发现了一些类似的问题(有答案)。但它们无济于事,因为许多已经过时。它们工作,直到我将它们重写为承诺,然后我回到我开始的地方。

我还可以使用 8 种不同的方式来完成这项工作,使用 npm 模块或 vanilla 代码,但它们都以一种或另一种方式失败。

标签: node.jspromise

解决方案


如果您已经有一个可以使用的承诺(并且promisepipe似乎创建了一个承诺),那么您通常不应该使用new Promise(). 看起来你的主要问题是你正在创建你永远不会解决的承诺。

另一个问题是您final_function在最后一行调用而不是传递将调用final_function.

我建议尝试一下:

var promises = files.map(function(file_enc) {
  var file_out = file_enc + '.locked';

  return promisePipe(
      fs.createReadStream(file_enc),
      crypt.createCipheriv(alg, genhashsub, iv),
      fs.createWriteStream(file_out),
  ).then(function(streams){
     console.log('File written: ' + file_out);

     return file_out;
  }, function(err) {
    if(err.message.substring(0, 7) === 'EACCES:') {
      console.log('Error (file ' + file_out + '): Insufficient rights on file or folder');
    } else {
      console.log('Error (file ' + file_out + '): ' + err);
    }

    throw new Error(err);
  });
});

Promise.all(promises).then(() => final_function(argument));

推荐阅读