0

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

Library1.js 设置了 Library2.js 需要的一些全局变量。

输出是(翻译成这个例子):

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

如果我在 library1 中手动插入另一个注释,其中设置了全局变量(它位于 library1 中的另一个函数内,在 library1 结束之前立即调用),上面写着“我已被设置”,我得到这个(如,没有变化) :

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

如果我手动插入甚至一秒的 setTimeout,那么我会得到:

started1
ended1
I've been set
started2
ended2

这里可能会发生什么?显然有一些我没有预料到的异步行为。会是什么呢?对我来说奇怪的是 library1 脚本实际上完全结束了,我仍然得到这个错误。如果生成了一些线程来处理 library1 中的函数调用,这种行为将是有意义的,但我的理解是,虽然 Node.js 是非阻塞的,但它不会为每个函数调用生成新线程。我错了吗?它是单线程但所有调用函数的时间共享吗?在这一点上我只是猜测,试图理解这种行为。

编写以下内容只是为了测试 Node 是否像我想的那样工作,而且似乎确实如此:

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

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

x();
y();

这会输出很多 'x' 后跟 'startedY',这似乎证实 Node 在移动到下一个函数之前完成了一个函数的工作(直到它返回)。

4

1 回答 1

0

好的,所以这最终不是 Node.js 中的意外行为,只是大型库 (YUI) 中的意外(未知)行为。YUI 做了一些我没想到的异步加载,当变量被分配给它时,它会抛出。仍在寻找解决方案,但作为 YUI 问题而不是 Node.js 问题。

我建议将这个线程留在这里,以防万一有人遇到同样的问题,以便他们看到可能是他们的库而不是 Node.js 导致了问题。

于 2012-07-03T20:59:35.317 回答