如何处理循环依赖? [重复]

问题描述 投票:1回答:1

这个问题在这里已有答案:

鉴于:

  • StringPreconditions延伸ObjectPreconditions
  • ObjectPreconditions依赖于StringPreconditions(其中一个方法返回子类)
  • PreconditionsObjectPreconditionsStringPreconditions的守门人(确保他们在返回实例之前加载)
  • User依赖于Preconditions

我有这个代码:

define(["ObjectPreconditions"], function(ObjectPreconditions)
{
  console.log("Inside StringPreconditions");

  function StringPreconditions() {}
  StringPreconditions.prototype = Object.create(ObjectPreconditions.prototype);
  StringPreconditions.prototype.constructor = ObjectPreconditions;
  return StringPreconditions;
});

define(["require"], function(require)
{
  console.log("Inside ObjectPreconditions");

  // Resolve circular dependencies
  var StringPreconditions;
  require(["StringPreconditions"], function(theStringPreconditions)
  {
    StringPreconditions = theStringPreconditions;
    console.log("ObjectPreconditions finished loading StringPreconditions");
  });

  function ObjectPreconditions() {}
  ObjectPreconditions.prototype.isInstanceOf(type)
  {
    console.log("ObjectPreconditions.isInstanceOf() invoked");
    if (type === String)
      return new StringPreconditions();
  }
});

define(["ObjectPreconditions", "StringPreconditions"], function(ObjectPreconditions, StringPreconditions)
{
  console.log("Inside Preconditions");
  var Preconditions = {};

  Preconditions.requireThat(parameter) = function()
  {
    return new ObjectPreconditions(parameter);
  };
  return Preconditions;
});

define(["Preconditions"], function(Preconditions)
{
  console.log("Inside User");
  function User() {}
  User.prototype.doSomething = function()
  {
    var StringPrecondition = Preconditions.requireThat("test").isInstanceOf(String);
  }
});

问题是我有10%的时间得到这个加载顺序:

  • 内部用户
  • 内部先决条件
  • 内部ObjectPreconditions
  • 在StringPreconditions中
  • ObjectPreconditions.isInstanceOf()(CRASH,因为未定义StringPreconditions)
  • ObjectPreconditions完成加载StringPreconditions

我已经阅读过http://requirejs.org/docs/api.html#circular,但我相信他们正在做同样的事情。

有任何想法吗?

requirejs circular-dependency
1个回答
1
投票

更新:https://stackoverflow.com/a/42264822/14731包含ES6模块的更新答案。


我想通了:我们需要创建一个“关守”文件,它将定义依赖于循环依赖关系的函数。

  1. ObjectPreconditions.js重命名为AbstractObjectPreconditions.js
  2. 创建一个新的ObjectPreconditions.js文件(我们的新网守)。
  3. 将任何循环依赖项从AbstractObjectPreconditions.js移到ObjectPreconditions.js
  4. 用户代码应该是require(ObjectPreconditions)。循环依赖中涉及的代码(例如子类)应该是require(AbstractObjectPreconditions)

以下是生成的代码:

define(["AbstractObjectPreconditions"], function(ObjectPreconditions)
{
  console.log("Inside StringPreconditions");

  function StringPreconditions() {}
  StringPreconditions.prototype = Object.create(ObjectPreconditions.prototype);
  StringPreconditions.prototype.constructor = ObjectPreconditions;
  return StringPreconditions;
});

define(["require"], function(require)
{
  console.log("Inside AbstractObjectPreconditions");

  function ObjectPreconditions() {}
  return ObjectPreconditions;
});

define(["AbstractObjectPreconditions"], function(ObjectPreconditions)
{
  // Gatekeeper for circular dependencies
  ObjectPreconditions.prototype.isInstanceOf(type)
  {
    console.log("ObjectPreconditions.isInstanceOf() invoked");
    if (type === String)
      return new StringPreconditions();
  }

  return ObjectPreconditions;
});


define(["ObjectPreconditions", "StringPreconditions"], function(ObjectPreconditions, StringPreconditions)
{
  console.log("Inside Preconditions");
  var Preconditions = {};

  Preconditions.requireThat(parameter) = function()
  {
    return new ObjectPreconditions(parameter);
  };
  return Preconditions;
});

define(["Preconditions"], function(Preconditions)
{
  console.log("Inside User code");
  function User() {}
  User.prototype.doSomething = function()
  {
    var StringPrecondition = Preconditions.requireThat("test").isInstanceOf(String);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.