使用递归函数时如何避免模块之间的循环依赖?

时间:2020-08-14 14:33:10

标签: javascript recursion es6-modules circular-dependency

以下代码遍历对象及其键。它根据所指的值对每个键执行操作。它运作良好。一切都很好。

const obj = {
  prop1: {
    prop2: 1,
    prop3: {
      prop4: 2
    }
  },
  prop5: "1"
}

function inspectRecursively(node) {
  switch (typeof node) {
    case "object":
      handleObject(node);
      break;
    case "string":
      handleString(node);
      break;
    case "number":
      handleNumber(node);
      break;
    default:
      break;
  }
}

function handleObject(node) {
  console.log(JSON.stringify(node, null, 2))
    
  for (const [key] of Object.entries(node)) {
    inspectRecursively(node[key]);
  }
}

function handleString(node) {
  console.log(node)
}

function handleNumber(node) {
  console.log(node.toString().padStart("0", 3))
}

inspectRecursively(obj)

说我认为文件太大了。我将其拆分为模块

main.js

import { importRecursively } from "./importRecursively"

const obj = {
  prop1: {
    prop2: 1,
    prop3: {
      prop4: 2
    }
  },
  prop5: "1"
}
 inspectRecursively(obj)

importRecursively.js

import { handleObject } from "./handleObject.js"
import { handleString} from "./handleString.js"
import { handleNumber} from "./handleNumber.js"

function inspectRecursively(node) {
  switch (typeof node) {
    case "object":
      handleObject(node);
      break;
    case "string":
      handleString(node);
      break;
    case "number":
      handleNumber(node);
      break;
    default:
      break;
  }
}

handleObject.js

import { importRecursively } from "./importRecursively"

function handleObject(node) {
  console.log(JSON.stringify(node, null, 2))
    
  for (const [key] of Object.entries(node)) {
    inspectRecursively(node[key]);
  }
}

handleString.js

function handleString(node) {
  console.log(node)
}

handleNumber.js

function handleNumber(node) {
  console.log(node.toString().padStart("0", 3))
}

现在,我最终遇到了循环依赖。

main -> inspectRecursively -> handleObject -> importRecursively

我认为这很糟糕,但是不确定吗?

在这种情况下我该怎么办?我是否需要更改某些内容以避免循环依赖?

2 个答案:

答案 0 :(得分:1)

我认为这很糟糕,但是不确定吗?

不,还不错。 ES6模块确实可以很好地处理循环依赖关系。只要确保所有这些模块都是纯模块,并且仅包含函数声明,而不是构建依赖于导入值的顶级代码即可:在模块之间“悬挂”了声明。

我是否需要更改某些内容以避免循环依赖?

您可以通过使用显式依赖项注入:

// inspectRecursively.js
import { makeHandleObject } from "./handleObject.js"
import { handleString} from "./handleString.js"
import { handleNumber} from "./handleNumber.js"

const handleObject = makeHandleObject(inspectRecursively);

function inspectRecursively(node) {
  …
}
// handleObject.js

export function makeHandleObject(inspectRecursively) {
  return function handleObject(node) {
    …
  };
}

答案 1 :(得分:-1)

我将Inspect编写为自己的模块-

// Inspect.js

const inspect = v =>
  // ...

const handleString = e =>
  // ...

const handleObject = e =>
  // ...

const handleNumber = e =>
  // ...

export { inspect } // only export functions the user should call

我真的看不到将每个handle*分解成自己的文件的目的。

现在在您的程序中使用它时-

import { inspect } from './Inspect'

inspect(someObj) // => ...