我有一個 node.js 腳本,它從檔案中讀取一些 JS 代碼,并將其傳遞給eval(). 將 javascript 傳遞給 eval 的代碼如下:
// read javascript code from file
var outputbuffer = '';
function output(data) {
outputbuffer = data '\n';
}
eval(javascriptCodeFromFile);
// do stuff with outputbuffer
檔案中的javascript代碼如下:
var fs = require('fs');
fs.readFile('myfile.txt', function(err, data) {
if (err) {
output('Error reading file');
}
else {
output(data.toString());
}
});
問題是 eval 在檔案讀取完成之前退出,因為檔案讀取是異步的。eval 只是開始讀取檔案,然后退出,而不是等待檔案讀取完成。如何讓 eval 在退出之前等待回呼?我看過承諾,它們看起來很有希望(雙關語),但我需要有人指導我朝著正確的方向前進。
uj5u.com熱心網友回復:
撇開 eval 的所有缺點,這里是您問題的直接答案。
創建一個讓主執行緒的事件回圈保持忙碌的承諾。
從正在評估的腳本中決議承諾。該腳本將可以訪問resolve and Promise的reject` 函式,因為評估腳本在 Promise 的范圍內。
let p = new Promise((resolve, reject) => eval(javascriptCodeFromFile));
p.then(()=> console.log(outputbuffer))
.catch((e) => console.log('Rejected ::' outputBuffer));
這是一個可運行的示例,演示了主執行緒在 eval 中等待異步執行發生
let jsCode = `
setTimeout(() => (resolve('Hello from eval after two seconds')), 2000);
`;
console.log('waiting...');
let p = new Promise((resolve, reject) => {
eval(jsCode);
})
p.then((data)=> console.log(data));
uj5u.com熱心網友回復:
讓您的 eval 代碼回傳一個承諾很好。
例子:
const code = `
new Promise((resolve, reject) => {
var fs = require('fs');
fs.readFile('myfile.txt', function (err, data) {
if (err) {
reject('Error reading file');
}
else {
resolve(data.toString());
}
});
});
`;
console.log('starting...');
eval(code)
.then(str => console.log(str))
.catch(err => console.error(err));
也可以將 Promise 置于 外部eval并從 eval 代碼中呼叫resolve或reject:
例如:
const code = `
var fs = require('fs');
fs.readFile('myfile.txt', function (err, data) {
if (err) {
reject(err);
}
else {
resolve(data.toString());
}
});
`;
console.log('starting...');
new Promise((resolve, reject) => eval(code))
.then(str => console.log(str))
.catch(err => console.error(err));
或await與呼叫異步版本相同的事情readFile
const code = `
require('fs').promises.readFile('myfile.txt')
`;
console.log('starting...');
main().then(() => console.log('...done'));
async function main() {
try {
let result = await eval(code);
console.log(result);
} catch(err) {
console.error(err);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318782.html
標籤:javascript 节点.js 异步 评估
