How to handle circular dependencies?

Given:

  • StringPreconditions extends ObjectPreconditions
  • ObjectPreconditions depends on StringPreconditions (one of its methods returns a subclass)
  • Preconditions is a gatekeeper with ObjectPreconditions and StringPreconditions (make sure they both load before returning an instance)
  • User Depends on Preconditions

I have this code:

 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); } }); 

The problem is that in 10% of cases I get this load order:

  • Inside user
  • Internal background
  • Inside ObjectPreconditions
  • Inside StringPreconditions
  • ObjectPreconditions.isInstanceOf () ( CRASH since StringPreconditions undefined)
  • ObjectPreconditions completed loading StringPreconditions

I already read http://requirejs.org/docs/api.html#circular , but I believe that they do the same thing as me.

Any ideas?

+1
requirejs circular-dependency
Nov 07 '14 at 19:49
source share
1 answer

UPDATE: https://stackoverflow.com/a/3186263/2166128




I realized this: we need to create a gatekeeper file that will define functions that depend on circular dependencies.

  1. Rename ObjectPreconditions.js to AbstractObjectPreconditions.js .
  2. Create a new ObjectPreconditions.js file (our new gatekeeper).
  3. Move all circular dependencies from AbstractObjectPreconditions.js to ObjectPreconditions.js
  4. User code must require(ObjectPreconditions) . Code involved in circular dependency (e.g. subclasses) must require(AbstractObjectPreconditions) .

Here's what the resulting code looks like:

 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); } }); 
+1
Nov 07 '14 at 20:05
source share



All Articles