我怎么能等待回调从eval()返回之前?



我有一个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在退出之前等待回调?我看过承诺,他们似乎很有希望(双关语),但我需要有人引导我在正确的方向。

抛开eval的所有缺点,这里有一个直接的答案


创建一个承诺,以保持主线程的事件循环繁忙。

从正在eval的脚本中解析承诺。该脚本可以访问Promise的resolve andreject函数,因为求值脚本在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));

让你的eval代码返回一个promise是可以的。

的例子:

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的代码中调用resolvereject:

例如:

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的async版本也是一样的

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);
}
}

相关内容

  • 没有找到相关文章

最新更新