JavaScript NodeJS 如何使用 stream/promises 异步函数?
JavaScript NodeJS How to use stream/promises with async functions?
我在 Node.js 中有一个 JS 异步函数。比如说,它从 URL 下载一个文件并用它做一些事情,例如。解压它。我是这样写的,它可以工作,但是 eslint
告诉我有一股浓浓的代码味道:error Promise executor functions should not be async no-async-promise-executor
。 Async
是必需的,因为 body 函数中有 await fetch
。
我对streams
和async/await
不够熟练,无法自行更正。我想摆脱 Promise 并充分利用 async/await
。模块 stream/promises
似乎是从 Node-15 开始的方式,正如此处 所评论的那样。如何在这种情况下使用 await pipeline(...)
?也许有更好更短的方法?
函数如下:
function doSomething(url) {
return new Promise(async (resolve, reject) => {
try {
const fileWriteStream = fs.createWriteStream(someFile, {
autoClose: true,
flags: 'w',
});
const res = await fetch(url);
const body = res.body;
body
.pipe(fileWriteStream)
.on('error', (err) => {
reject(err);
})
.on('finish', async () => {
await doWhatever();
resolve('DONE');
});
} catch (err) {
reject(err);
}
});
}
您可以在 NodeJS 中使用 fs/promises
并且 trim 您的代码如下:
import { writeFile } from 'fs/promises'
async function doSomething(url) {
const res = await fetch(url);
if (!res.ok) throw new Error('Response not ok');
await writeFile(someFile, res.body, { encoding: 'utf-8'})
await doWhatever();
return 'DONE';
});
}
您可以在到达执行程序之前简单地执行 await
:
async function doSomething(url) {
const fileWriteStream = fs.createWriteStream(someFile, { autoClose: true, flags: 'w' });
let { body } = await fetch(url);
body.pipe(fileWriteStream);
return new Promise((reject, resolve) => {
body.on('error', reject);
body.on('finish', resolve);
});
};
总的来说,我的建议是尽可能多地从 promise 执行器中删除代码。在这种情况下,Promise 只需要捕获 resolution/rejection.
请注意,我还从 doSomething
中删除了 doWhatever
- 这使 doSomething
更加健壮。你可以简单地做:
doSomething('http://example.com').then(doWhatever);
最后,我建议您将 someFile
设置为 doSomething
的参数,而不是从更广泛的上下文中引用它!
要使用您正在寻找的 pipeline
函数,应该是
const { pipeline } = require('stream/promises');
async function doSomething(url) {
const fileWriteStream = fs.createWriteStream(someFile, {
autoClose: true,
flags: 'w',
});
const res = await fetch(url);
await pipeline(res.body, fileWriteStream);
await doWhatever();
return 'DONE';
}
我在 Node.js 中有一个 JS 异步函数。比如说,它从 URL 下载一个文件并用它做一些事情,例如。解压它。我是这样写的,它可以工作,但是 eslint
告诉我有一股浓浓的代码味道:error Promise executor functions should not be async no-async-promise-executor
。 Async
是必需的,因为 body 函数中有 await fetch
。
我对streams
和async/await
不够熟练,无法自行更正。我想摆脱 Promise 并充分利用 async/await
。模块 stream/promises
似乎是从 Node-15 开始的方式,正如此处 await pipeline(...)
?也许有更好更短的方法?
函数如下:
function doSomething(url) {
return new Promise(async (resolve, reject) => {
try {
const fileWriteStream = fs.createWriteStream(someFile, {
autoClose: true,
flags: 'w',
});
const res = await fetch(url);
const body = res.body;
body
.pipe(fileWriteStream)
.on('error', (err) => {
reject(err);
})
.on('finish', async () => {
await doWhatever();
resolve('DONE');
});
} catch (err) {
reject(err);
}
});
}
您可以在 NodeJS 中使用 fs/promises
并且 trim 您的代码如下:
import { writeFile } from 'fs/promises'
async function doSomething(url) {
const res = await fetch(url);
if (!res.ok) throw new Error('Response not ok');
await writeFile(someFile, res.body, { encoding: 'utf-8'})
await doWhatever();
return 'DONE';
});
}
您可以在到达执行程序之前简单地执行 await
:
async function doSomething(url) {
const fileWriteStream = fs.createWriteStream(someFile, { autoClose: true, flags: 'w' });
let { body } = await fetch(url);
body.pipe(fileWriteStream);
return new Promise((reject, resolve) => {
body.on('error', reject);
body.on('finish', resolve);
});
};
总的来说,我的建议是尽可能多地从 promise 执行器中删除代码。在这种情况下,Promise 只需要捕获 resolution/rejection.
请注意,我还从 doSomething
中删除了 doWhatever
- 这使 doSomething
更加健壮。你可以简单地做:
doSomething('http://example.com').then(doWhatever);
最后,我建议您将 someFile
设置为 doSomething
的参数,而不是从更广泛的上下文中引用它!
要使用您正在寻找的 pipeline
函数,应该是
const { pipeline } = require('stream/promises');
async function doSomething(url) {
const fileWriteStream = fs.createWriteStream(someFile, {
autoClose: true,
flags: 'w',
});
const res = await fetch(url);
await pipeline(res.body, fileWriteStream);
await doWhatever();
return 'DONE';
}