[英]How can I make a readline await async promise?
On NodeJS I need to make a grep like function for log research purposes and I'm trying to make it using readline (since I don't want readline-sync).在 NodeJS 上,我需要为日志研究目的创建一个类似 grep 的函数,我正在尝试使用 readline 来实现它(因为我不想要 readline-sync)。 I've read many messages, tutorials, documentation, stackoverflow posts, and so on, but I couldn't understood how to make it works.
我已经阅读了许多消息、教程、文档、stackoverflow 帖子等,但我无法理解如何使其工作。
const grep = async function(pattern, filepath){
return new Promise((resolve, reject)=>{
let regex = new RegExp(pattern);
let fresult = ``;
let lineReader = require(`readline`).createInterface({
input: require(`fs`).createReadStream(filepath)
});
lineReader.on(`line`, function (line) {
if(line.match(regex)){
fresult += line;
}
});
resolve(fresult);
});
}
let getLogs = await grep(/myregex/gi, filepath);
console.log(getLogs);
Which gives me:这给了我:
SyntaxError: await is only valid in async functions and the top level bodies of modules
SyntaxError: await 仅在异步函数和模块的顶级主体中有效
Where am I wrong?我哪里错了? I feel like I'm good but did a beginner mistake which is dancing just under my eyes.
我觉得我很好,但犯了一个初学者的错误,那就是在我的眼睛下跳舞。
What the other answers have missed is that you have two problems in your code.其他答案遗漏的是您的代码中有两个问题。
Top level await ( await
not wrapped in an async
function) is only possible when running Node.js "as an ES Module", which is when you are using import {xyz} from 'module'
rather than const {xyz} = require('module')
.只有在“作为 ES 模块”运行 Node.js 时,才可能使用顶级 await(
await
未包含在async
函数中),即当您使用import {xyz} from 'module'
而不是const {xyz} = require('module')
。
As mentioned, one way to fix this is to wrap it in an async function:如前所述,解决此问题的一种方法是将其包装在异步函数中:
// Note: You omitted the ; on line 18 (the closing } bracket)
// which will cause an error, so add it.
(async () => {
let getLogs = await grep(/myregex/gi, filepath);
console.log(getLogs);
})();
A different option is to save your file as .mjs
, not .js
.另一种选择是将文件另存为
.mjs
,而不是.js
。 This means you must use import
rather than require
.这意味着您必须使用
import
而不是require
。
The third option is to create a package.json
and specify "type": "module"
.第三个选项是创建一个
package.json
并指定"type": "module"
。 Same rules apply.相同的规则适用。
When you call resolve()
the event handler in lineReader.on('line')
will not have been executed yet.当您调用
resolve()
, lineReader.on('line')
resolve()
的事件处理程序还没有被执行。 This means that you will be resolving to an empty string and not the user's input.这意味着您将解析为空字符串而不是用户的输入。 Declaring a function
async
does nothing to wait for events/callbacks, after all.毕竟,声明一个函数
async
对等待事件/回调没有任何作用。
You can solve this by waiting for the 'close' event of Readline & only then resolve the promise.您可以通过等待 Readline 的“关闭”事件来解决此问题,然后才解决承诺。
const grep = async function(pattern, filepath){
return new Promise((resolve, reject)=>{
let regex = new RegExp(pattern);
let fresult = ``;
let lineReader = require(`readline`).createInterface({
input: require(`fs`).createReadStream(filepath)
});
lineReader.on(`line`, function (line) {
if(line.match(regex)){
fresult += line;
}
});
// Wait for close/error event and resolve/reject
lineReader.on('close', () => resolve(fresult));
lineReader.on('error', reject);
});
}; // ";" was added
(async () => {
let getLogs = await grep(/myregex/gi, 'foo');
console.log("output", getLogs);
})();
The events
module has a handy utility function named once
that allows you to write your code in a shorter and clearer way: events
模块有一个名为once
的方便的实用程序函数once
它允许您以更短更清晰的方式编写代码:
const { once } = require('events');
// If you're using ES Modules use:
// import { once } from 'events'
const grep = async function(pattern, filepath){
// Since the function is 'async', no need for
// 'new Promise()'
let regex = new RegExp(pattern);
let fresult = ``;
let lineReader = require(`readline`).createInterface({
input: require(`fs`).createReadStream(filepath)
});
lineReader.on(`line`, function (line) {
if(line.match(regex)){
fresult += line;
}
});
// Wait for the first 'close' event
// If 'lineReader' emits an 'error' event, this
// will throw an exception with the error in it.
await once(lineReader, 'close');
return fresult;
};
(async () => {
let getLogs = await grep(/myregex/gi, 'foo');
console.log("output", getLogs);
})();
// If you're using ES Modules:
// leave out the (async () => { ... })();
try this:尝试这个:
async function run(){
let getLogs = await grep(/myregex/gi, `/`);
console.log(getLogs);
}
run();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.