4

Node.js VM で「順次記述された」非同期 JS コードを実行し、それぞれのコンテキスト オブジェクトにアクセスする方法を実装しようとしています。によってトランスパイルされた、今後の ES7await機能を使用しようとしています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);

同期的な方法でコンテキスト評価から非同期の結果を取得する方法はありますか?

参考文献:

4

4 に答える 4

4

これを機能させる方法を見つけました...基本的にthisは、実行されたコード内でコンテキストオブジェクトの変数を使用し、最後の操作として内部からコールバック関数を呼び出します:

var vm = require('vm');
var babel = require("babel-core");

// VM context object
var context = {
    require: require,
    callback: function(error) {
        if (error) {
            console.log(error.stack);
        } else {
            console.log(this.response);
        }
    }
};

// ES 7 code
var code = "var request = require('request-promise'); var response = await request({ url: 'https://graph.facebook.com/?id=http://news.ycombinator.com', json: true })";

// Wrap the code
code = "'use strict'; async function run() { try { " + code.replace(/var /g, "this.") + "; this.callback(null); } catch(error) { this.callback(error); } }; run.apply(this)";

// Transpile code ES7 -> ES5
var regeneratedCode = babel.transform(code, { "ast": false, "presets": ["stage-0"] }).code;

// Create VM context
var vmContext = new vm.createContext(context);

// Create virtual script
var script = new vm.Script(regeneratedCode);

// Run script
script.runInContext(vmContext, {displayErrors: true, timeout: 30000});
于 2015-12-08T19:27:39.857 に答える