简体   繁体   English

Node.js中意外的vm.runInThisContext控制流

[英]Unexpected vm.runInThisContext control flow in Node.js

I am writing a Node.js script that looks like this: 我正在编写一个如下所示的Node.js脚本:

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和library2.js最初是为Web编写的,因此,据我所知,它们不执行任何文件系统调用或其他任何将导致意外异步的操作。

Library1.js sets some global variables that Library2.js needs. Library1.js设置Library2.js需要的一些全局变量。

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): 如果我在设置了全局变量的library1中手动插入另一条注释(该注释在library1的另一个函数内部,在library1结束前立即调用),说“我已经设置好了”,我就得到了(例如,没有任何改变) :

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: 如果我手动插入setTimeout甚至一秒钟,那么我会得到:

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. 对我来说奇怪的是,library1脚本实际上完全结束了,但我仍然收到此错误。 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. 如果在library1中派生了一些线程来处理函数调用,那么这种行为就很有意义,但是我的理解是,尽管Node.js处于非阻塞状态,但它不会为每个函数调用都产生新的线程。 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: 编写以下内容只是为了测试Node是否像我所想的那样工作,并且看起来确实可以:

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. 这会输出很多“ x”,后跟“ startedY”,这似乎可以确认Node在移至下一个函数之前已完成对一个函数的工作(直到返回)。

Okay, so this ended up not being unexpected behavior in Node.js, just unexpected (unknown) behavior inside a large library (YUI). 好的,所以最终这不是Node.js中的意外行为,而只是大型库(YUI)中的意外(未知)行为。 YUI does some asynchronous loading that I wasn't expecting that threw off when variables were assigned to. YUI会执行一些异步加载,但我并不期望在将变量分配给它时抛出该异步加载。 Still looking for a solution for that but as a YUI issue rather than a Node.js issue. 仍然在寻找一种解决方案,但是它是一个YUI问题,而不是Node.js问题。

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. 我建议将这个线程留在这里,以防万一有人遇到相同的问题,以便他们看到可能是由自己的库而不是Node引起了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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