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,
);
}
文件: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,
);
}