为什么我不能有两个互相执行的.js脚本?

问题描述 投票:0回答:3

我有两个.js文件:/Desktop/firstFolder/first.js/Desktop/secondFolder/second.js。我希望first首先工作,然后执行second。在second的结尾,我希望它再次执行first,依此类推。听起来很简单,对吧?

first正常工作,然后second完成工作,然后停止工作。为什么我不能第二次执行first

因此firstsecond脚本尽可能简单:

console.log('first.js works, launching second.js');
process.chdir('/Users/apple/Desktop/secondFolder');
require('/Users/apple/Desktop/secondFolder/second.js');
console.log('second.js works, launching first.js');
process.chdir('/Users/apple/Desktop/firstFolder');
require('/Users/apple/Desktop/firstFolder/first.js');

来自终端的日志:

first.js works, launching second.js
second.js works, launching first.js
Apples-MacBook-Air:firstFolder apple$ 

为什么它停止工作? JavaScript是否可以防止自己陷入无限循环?有没有办法做到这一点?

[suggested question,但是有所不同,因为他们询问如何使一个.js文件多次执行另一个.js文件,而不是彼此执行两个.js文件。而且,我尝试对我的代码执行相同的操作,将两个.js文件都包装在module.exports = function() {}中,并在每个()的末尾添加了一个额外的require,但现在它会引发错误:

  require('/Users/apple/Desktop/firstFolder/first')();
                                                   ^

TypeError: require(...) is not a function

javascript node.js directory infinite-loop require
3个回答
2
投票

节点模块系统是为模块构建的,这意味着require的语义是“需要”而不是“执行”。两个模块在逻辑上不能简单地相互要求才能存在,但是它们的导出却可以,因此这是Node通过递归require为您提供的行为:您可以获取已经在运行的模块的export对象的当前值。

因此,请从模块中导出功能:

const second = require('/Users/apple/Desktop/secondFolder/second.js');

exports.run = () => {
    console.log('first.js works, launching second.js');
    process.chdir('/Users/apple/Desktop/secondFolder');
    second.run();
};
const first = require('/Users/apple/Desktop/firstFolder/first.js');

exports.run = () => {
    console.log('second.js works, launching first.js');
    process.chdir('/Users/apple/Desktop/firstFolder');
    first.run();
};

这应该引发堆栈溢出错误。 (如果您不希望出现堆栈溢出错误,请用不保留堆栈的内容替换运行调用,例如process.nextTick(first.run)。)


1
投票

看起来'执行文件'只是意味着需要它,因为在代码中需要它之后您无需调用任何函数。

节点不会两次执行所需的文件。相反,第一次需要文件时,它将执行整个文件并从您的module.exports中生成一些内容,然后,如果您再次需要相同的文件,则只需再次提供您的module.exports

因此,您应该做的是让文件既导出要执行的功能,又在每个文件中执行该功能。

例如,在文件2中,您有module.exports = function(){...}。在文件1中,执行var file2 = require('./file2'); file2();

然后执行相同的操作以在文件2中执行文件1。

然后您可能需要一个需要file1的入口文件,然后调用它,var file1 = require('./file1'); file1();


0
投票

JS文件一旦通过nodejs中的require()调用就存储在缓存中,因此控制台仅被调用一次,并且当两个文件都加载时,它将等待事件发生或其他函数执行。

您可以在https://nodejs.org/api/modules.html#modules_require_id中阅读更多内容>

如果要永久循环,请使用for,foreach和while中的一种。

© www.soinside.com 2019 - 2024. All rights reserved.