首页 > 解决方案 > 与 arguments.callee 一起使用的间隔打破了“要求”行为

问题描述

我对为什么有些“要求”感到相当困惑

返回错误:

TypeError: require is not a function at Timeout._onTimeout (.......index.js:8:18)

执行以下操作时:

(()=> {
  console.time("pipeline")
  pipeline().then((result) => {
    console.log("Then: " + result)
    console.log("Work Complete for iteration: " + i + " calling iteration no:", i = i + 1)
    setTimeout(arguments.callee, 1000);
  }).catch((error) => {
    console.error("error occured with promise resolution: " + error)
  });
  console.timeEnd("pipeline")
})()

它运行一次然后出错(即使我显然已连接到数据库)

但更改为这种格式时按预期工作:

(function () {
  console.time("pipeline")
  pipeline().then((result) => {
    console.log("Then: " + result)
    console.log("Work Complete for iteration: " + i + " calling iteration no:", i = i + 1)
    setTimeout(arguments.callee, 1000);
  }).catch((error) => {
    console.error("error occured with promise resolution: " + error)
  });
  console.timeEnd("pipeline")
})()

该错误表明这与我认为的超时有关,因为它在引发错误之前执行一次。

为什么会发生这种行为?这与 arguments.callee 有关吗?如果是,为什么?

提前致谢,

标签: node.jsarrow-functions

解决方案


arguments在箭头函数的情况下指父函数范围。箭头函数没有自己的arguments.

Node.js 模块在底层使用模块包装器函数进行包装:

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});

这就是arguments.callee指内部箭头功能。特别是,调用arguments.callee会导致使用错误的参数再次评估当前模块require

依赖arguments.callee是hacky。更好的方法是显式引用一个函数:

(function foo() {
  ...
  setTimeout(foo, 1000);
  ...
})()

虽然箭头将要求块范围不泄漏foo到父范围:

{
  let foo;
  (foo = () => {
    ...
    setTimeout(foo, 1000);
    ...
  })()
}

推荐阅读