NodeJS Stream Pipeline - "val" 参数必须是 Readable、Iterable 或 AsyncIterable 的实例。接收到 WriteStream 的实例

NodeJS Stream Pipeline - The "val" argument must be an instance of Readable, Iterable, or AsyncIterable. Received an instance of WriteStream

文件:index3.js

#!/usr/bin/env node

'use strict';

import { pipeline } from 'stream/promises'
import { realpathSync, createReadStream, createWriteStream } from 'fs';
import { pathToFileURL } from 'url';

async function doStuff() {
    return new Promise((resolve, reject) => {
        let readStream = createReadStream("input.js");
        let writeStream = createWriteStream("output.js");

        pipeline(
            readStream,
            writeStream,
            async(err) => {
                if (err) {
                    console.error('failed', err);
                    reject({res:'Pipeline failed', err});
                } else {
                    console.log('succeeded');
                    resolve('succeeded');

                }
            }
        );
    });
}

export default function myFunc() {
    doStuff().catch(err => console.log(err));
}

function wasCalledAsScript() {
    const realPath = realpathSync(process.argv[1]);
    const realPathAsUrl = pathToFileURL(realPath).href;
    return import.meta.url === realPathAsUrl;
}

if (wasCalledAsScript()) {
    myFunc();
}

运行 节点 v16.15.0

# node index3.js 
node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "val" argument must be an instance of Readable, Iterable, or AsyncIterable. Received an instance of WriteStream
    at new NodeError (node:internal/errors:372:5)
    at makeAsyncIterable (node:internal/streams/pipeline:100:9)
    at pipelineImpl (node:internal/streams/pipeline:263:13)
    at node:stream/promises:28:5
    at new Promise (<anonymous>)
    at pipeline (node:stream/promises:17:10)
    at file:///var/www/html/index3.js:14:9
    at new Promise (<anonymous>)
    at doStuff (file:///var/www/html/index3.js:10:12)
    at myFunc (file:///var/www/html/index3.js:32:5) {
  code: 'ERR_INVALID_ARG_TYPE'
}

我已经尝试了所有我能想到的 async 和 await 等组合,但每次尝试使用 createWriteStream 时都会出现此错误。我最终想在此处添加一个 Transform 以在编写之前修改每个 ,(我喜欢一个如何使用 pipeline 进行修改的示例,因为大多数在线教程都使用 pipe,) 但我什至无法进行简单的先读后写工作。

问题是您正在这样做:

import { pipeline } from 'stream/promises'

这让你得到 pipeline() 的版本,它已经 returns 一个承诺并且不接受常规回调作为最后一个参数。但是,你正在向它传递一个回调。由于它不使用回调,它期望参数是回调以外的其他东西,因此你会得到一个错误。

您可以切换到这个:

import { pipeline } from 'stream'

因此,您将获得使用回调的管道版本。

或者,由于您似乎确实想要承诺,所以不要传递回调并使用 import { pipeline } from 'stream/promises' 中的 pipeline() 已经 returns.[=16 的承诺=]

function doStuff() {
    let readStream = createReadStream("input.js");
    let writeStream = createWriteStream("output.js");

    return pipeline(
        readStream,
        writeStream,
    );
}