1

リクエストごとに vm.runInNewContext で別のスクリプトを実行する handleRequest コールバックを備えた http サーバーがあります。vm.runInNewContext 内で実行されるスクリプトは、いくつかの非同期 HTTP ポスト リクエストを作成し、ポストからのレスポンスを取得した後にのみサーバー レスポンスを書き込みます。その結果、サーバー応答が書き込まれる前に、handleRequest コールバックのコードが終了します。安全ですか?または、この状況を回避する方法はありますか?

ここにいくつかのコードがあります:

var server = http.createServer(handleRequest);
server.listen(8080);

var handleRequest = function (request, response) {
    // get request data...

    var context = {
        ServerRequest : request,
        ServerResponse : response
     };

     var stringScript = // a string with the script that posts data
     var script = vm.createScript(stringScript);
     script.runInNewContext({ context: context });
}

スクリプト文字列はこれを行います:

var request = require('request');
var options = {....}
var req = request.get(options);

    req.on('response', function (res) {
            var chunks = [];
            res.on('data', function(chunk) {
                chunks.push(chunk);
            });

            res.on('end', function() {
                var buffer = Buffer.concat(chunks);
                var encoding = res.headers['content-encoding'];
                if (encoding == 'gzip') {
                    zlib.gunzip(buffer, function(err, decoded) {
                        // set response headers and write the response
                        context.ServerResponse.end(decoded.toString()); 
                    });
                } else if (encoding == 'deflate') {
                    zlib.inflate(buffer, function(err, decoded) {
                    // set response headers and write the response                            
                    context.ServerResponse.end(decoded.toString());
                    })
                } else {
                    // set response headers and write the response                                                    
                    context.ServerResponse.end(buffer.toString());
                }
            });

    });
4

1 に答える 1

0

簡単な解決策: VM スクリプトからpromise を返します (たとえば、Q-libraryを使用します)。
script.runInNewContextVMスクリプトから返されたものは何でも返します。そうすれば、VM コードが終了したときの「コールバック」が得られます。

// Script for VM
// I simplified it. Just resolve or reject the promise whenever you are done with your work
'use strict';

var defer = q.defer();

doABarrelRoll(function() {
  defer.resolve('RESULT');
});

defer.promise; // This line will return the promise.


VM スクリプトから値を返す場合、return の構築は必要ありません。欲しいものを書くだけで、魔法が起こります。

// Script for current context
'use strict';

var server = http.createServer(handleRequest);
server.listen(8080);

var handleRequest = function (request, response) {
  // get request data...

  var context = {
    ServerRequest : request,
    ServerResponse : response
  };

  var stringScript = // a string with the script that posts data
  var script = vm.createScript(stringScript);
  var prom = script.runInNewContext({
    context: context,
    q: require('q'),
  });

  prom.done(function ($result) {
    console.log('VM finished with result: ' + $result);
  });
}    
于 2015-08-18T08:40:49.740 に答える