在 NodeJS 上,我需要為日志研究目的創建一個類似 grep 的函式,我正在嘗試使用 readline 來實作它(因為我不想要 readline-sync)。我已經閱讀了許多訊息、教程、檔案、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);
威奇給了我:
SyntaxError: await is only valid in async functions and the top level bodies of modules
我哪里錯了?我覺得我很好,但犯了一個初學者的錯誤,那就是在我的眼睛下跳舞。
uj5u.com熱心網友回復:
其他答案遺漏的是您的代碼中有兩個問題。
您問題中的錯誤:
只有在“作為 ES 模塊”運行 Node.js 時才可能使用頂級 await(await未包裝在async函式中),也就是當您使用import {xyz} from 'module'而不是const {xyz} = require('module').
如前所述,解決此問題的一種方法是將其包裝在異步函式中:
// 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);
})();
不同的選項是將您的檔案另存為.mjs,不是.js。這意味著您必須使用import而不是require.
第三個選項是創建一個package.json并指定"type": "module". 相同的規則適用。
一個更基本的問題:
當您呼叫resolve()事件處理程式時,lineReader.on('line')將尚未執行。這意味著您將決議為空字串而不是用戶的輸入。async畢竟,宣告一個函式對等待事件/回呼沒有任何作用。
您可以通過等待 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);
})();
一個提示
該events模塊有一個方便的實用程式函式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 () => { ... })();
uj5u.com熱心網友回復:
將函式呼叫包裝到異步IIFE 中:
(async()=>{
let getLogs = await grep(/myregex/gi, filepath);
console.log(getLogs);
})()
uj5u.com熱心網友回復:
嘗試這個:
async function run(){
let getLogs = await grep(/myregex/gi, `/`);
console.log(getLogs);
}
run();
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/345102.html
標籤:javascript 节点.js 异步等待 承诺 阅读线
上一篇:如何讓元素重新出現?
