次のような 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 を 1 秒でも挿入すると、次のようになります。
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 が次の関数に移動する前に、(関数が戻るまで) 1 つの関数の作業を完了したことを確認しているようです。