【发布时间】:2016-03-13 15:05:09
【问题描述】:
我正在尝试实现一种在 Node.js VM 中运行“按顺序编写”的异步 JS 代码并获得对相应上下文对象的访问权限的方法。我尝试使用即将到来的 ES7 await 功能,由 babel.js 转译。
在我看来,script.runInContext() 在后台运行,而主循环仍在继续,因此我无法从 VM 的上下文中获得结果。
我的示例代码如下:
var vm = require('vm');
var request = require('request-promise');
var babel = require("babel-core");
// VM context object
var contextCache = {
context: {
request: request
}
};
// ES 7 code
var code = "var res = await request('http://www.google.de')";
// Wrap the code
code = "(async function() { " + code + " })()";
// Transpile code ES7 -> ES5
var regeneratedCode = babel.transform(code, { "ast": false, "presets": ["stage-0"] }).code
// Create VM context
var vmContext = new vm.createContext(contextCache.context);
// Create virtual script
var script = new vm.Script(regeneratedCode);
// Run script
script.runInContext(vmContext, {displayErrors: true, timeout: 30000});
// Check if variable was set -> Is undefined
console.log(contextCache.context.res);
有没有办法以同步的方式从上下文评估中检索异步结果?
参考资料:
【问题讨论】:
-
我必须选择不,这是不可能的。如果不能在 ES5 或 ES2015 中完成,也无法在 ES7 中转译为 ES5 或 ES2015,除非使其同步而不是异步。
-
不确定是否“无法完成”...代码本身是正确的并且可以执行。这只是获得结果的问题。我认为问题在于我必须将 ES7 代码包装在异步 IIF 中,这会导致无法访问恕我直言...
-
嗯,不。 console.log 将在异步操作完成之前发生。它与达到它无关。尝试将 console.log 包装在一个长的 setTimeout 中,看看我的意思。
-
是的,但如果我执行标准 ES5 而不进行转译和必要的 IIF,恕我直言,代码将同步执行...看看我正在尝试实现的类似示例:@987654326 @
-
啊,我才意识到为什么每个人都对这种异步/等待语法大发雷霆。它使这成为可能:pastebin.com/9hiEADe3 这基本上就是您想要做的吗? (我不明白 vm 模块是如何工作的。所以我改为在我自己的沙箱中运行它,该沙箱使用 require 挂钩编译到 ES5)
标签: node.js async-await babeljs ecmascript-2016