【问题标题】:Why can't I have two .js scripts which execute each other?为什么我不能有两个相互执行的 .js 脚本?
【发布时间】:2020-05-04 15:26:50
【问题描述】:

我有两个 .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

【问题讨论】:

  • 这能回答你的问题吗? Require multiple times
  • 它会抛出一个错误。 TypeError: require(...) is not a function

标签: javascript node.js directory infinite-loop require


【解决方案1】:

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

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

因此,您应该做的是让您的文件都导出您要执行的函数,并在每个文件中执行该函数。

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

然后在file2中执行file1。

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

【讨论】:

    【解决方案2】:

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

    所以改为从模块中导出您的功能:

    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)。)

    【讨论】:

    • 它不会抛出堆栈溢出错误。相反,什么也没有发生。没有登录终端,什么都没有。
    • @narra_kk:您必须通过调用导出的函数来启动它。从第三个文件,或if (require.main === exports) exports.run()
    • 我尝试在各个地方添加if (require.main === exports) exports.run(),但仍然没有任何反应。如何从第三个文件中调用它?
    【解决方案3】:

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

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

    如果您想要永远循环,请使用 for、foreach、while 之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2013-09-13
      • 2017-01-10
      相关资源
      最近更新 更多