简体   繁体   中英

Unexpected vm.runInThisContext control flow in Node.js

I am writing a Node.js script that looks like this:

var vm = require('vm');
var fs = require('fs');

vm.runInThisContext("console.log('started1');" + fs.readFileSync('library1.js') + "console.log('ended1');");

vm.runInThisContext("console.log('started2');" + fs.readFileSync('library2.js') + "console.log('ended2');"));

Library1.js and library2.js were originally written for the web, so they don't do any file system calls or anything else that would become unexpectedly asynchronous as far as I know.

Library1.js sets some global variables that Library2.js needs.

The output is (translated into this example):

started1
ended1
started2
ERROR, global variable was undefined and a property access caused the script to die

If I manually insert another comment in library1 where the global variable is set (which is inside another function in library1, called immediately before library1 ends), that says "I've been set", I get this (as in, no change):

started1
ended1
started2
ERROR, global variable was undefined and a property access caused the script to die

If I manually insert a setTimeout of even a second, then I get this:

started1
ended1
I've been set
started2
ended2

What might be happening here? Obviously there is some asynchronous behavior that I'm not expecting. What could it be? What's strange to me is that the library1 script actually ends completely and I still get this error. This behavior would make sense if there were some thread being spawned to deal with the function call in library1, but my understanding is that while Node.js is nonblocking it doesn't spawn new threads for every function call. Am I wrong about that? Is it single threaded but time-sharing on all called functions? Just speculation on my part at this point, trying to understand this behavior.

Wrote the following just to test whether Node works like I think, and it seems that it does:

function x() {
    for ( var i = 0; i < 100000; i++ ) {
        console.log('x');
    }
    console.log('loopedX');
}

function y() {
    console.log('startedY');
}

x();
y();

This outputs a lot of 'x's followed by 'startedY', which seems to confirm that Node completes the work on one function (until it returns) before moving to the next.

Okay, so this ended up not being unexpected behavior in Node.js, just unexpected (unknown) behavior inside a large library (YUI). YUI does some asynchronous loading that I wasn't expecting that threw off when variables were assigned to. Still looking for a solution for that but as a YUI issue rather than a Node.js issue.

I suggest leaving this thread here just in case someone has the same problem so they see that it's probably their library causing the issue rather than Node.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM