9

为了修复循环依赖性,请阅读requireJs文档
,建议使用exports为可立即供其他模块参考的模块创建空对象。使用requireJs的模块中的循环依赖关系

我尝试这段代码,但它似乎不起作用。哪里不对?

P.S:
阅读评论的看到setTimeout调用内部的输出,
尤其是B模块。


// A module 
define([ 
    'b' 
], function (b) { 
    console.log('B:', b); // B, Object 
    var A = { 
     boo: 1 
    }; 

    return A; 
}); 

// B module 
define([ 
    'a', 
    'exports' 
], function (a, exports) { 
    console.log('A:', a); // A, undefined (as I was expecting) 
    exports.A = function() { 
     return a; 
    } 

    var B = { 
     bar: 1 
    }; 

    setTimeout(function() { 
     console.log('exports.A', exports.A()); // exports.A undefined 
              // I would like to access the A object 
              // which is defined in A module 
    }, 500); 

    return B; 
}); 

// main.js 

(function() { 

    define([ 
     'a' 
    ], function() { 
    }); 
}()); 
+0

我认为这可能会有所帮助http://stackoverflow.com/questions/4771025/understanding-when-and-how-to-use-require-js?rq=1 – Jake

+0

@ lorraine-bernand你知道如何解决这个?上面的链接并没有给我足够的手柄来解决它。 – donnut

+0

我希望这是一个回答的问题。我一直遇到这个:) – SimplGy

回答

0

我经常使用AMD模块来构建应用程序的核心,这两个代表了许多模块,包含配置或其他有用的对象为那些问题的通知要使用的模块。

我今天做了一些试验,看起来效果很好。

define(['exports', 'underscore', './config', './mediator'], 
    function (exports, _, Backbone, config, Mediator){ 

    Core = /* ... */ 

    // Publicize a core 'singleton' so that it's dependencies can access it, and so can modules that define it as a dependency themselves. 
    core = new Core() 
    exports.core = core //publicize it in a way that supports circularity 
    return core // And also publicize it normally 
    } 
) 

对象都'==='彼此相等,所以这看起来很有前途。

编辑:

上述方法不优化时工作。这里是另一种方法,可以(未经测试): https://github.com/requirejs/example-multipage/blob/master/www/js/app/main1.js#L2

define(function (require) { 
    var $ = require('jquery'), 
     lib = require('./lib'), 
     Core; 

    Core = /* ... */ 

    return new Core() 
}); 
+0

其实我不会用这个方法。它适用于未优化的代码,但如果您在其上运行优化程序,则导出不可用,如下所示。 – SimplGy

+0

我现在正在努力解决这个循环依赖问题,所以我想知道你是否有一个建议的替代方案 –

+0

不幸的不是。这是一年左右的问题,我一直在使用RequireJS和CurlJS进行应用程序模块管理。我的“解决方案”是将对中介对象的引用传递给中介依赖的所有内容,并在“页面”级别启动新的依赖关系链。这看起来像这样:https://github.com/SimpleAsCouldBe/appCore/blob/master/shared/appCore/app.js#L45虽然这不是很好。我希望能够通过声明始终得到我的依赖关系:( – SimplGy

0

一个选项将不返回模块本身,而是实例化模块(在这个例子中,将一个构造为打字稿定义的函数,在底部是生成的js代码 - 音符该接口不产生的.js代码)

  • 文件IA.ts

    /// <reference path="IB.ts" /> 
    interface IA{ 
        funcA(); 
        _classB : IB; 
    } 
    
  • 文件IB.ts

    /// <reference path="IA.ts" /> 
    interface IB{ 
        funcB(); 
        _classA : IA; 
    } 
    
  • 文件ClassA.ts

    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    
    export class ClassA implements IA 
    { 
        _classB : IB = null; 
    
        constructor(classB : IB) 
        { 
         this._classB = classB; 
         if (classB){ 
          this._classB._classA = this; 
         } 
         return this; 
        } 
    
        funcA(){ 
         console.log('I am ClassA'); 
        } 
    } 
    
  • 文件ClassB.ts

    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    export class ClassB implements IB 
    { 
        _classA : IA = null; 
        constructor(classA : IA) 
        { 
         this._classA = classA; 
         if (classA){ 
          this._classA._classB = this; 
         } 
         return this; 
        } 
        funcB(){ 
         console.log('I am ClassB'); 
        } 
    } 
    
  • 文件MainTest.ts

    /// <reference path="../../def/require.d.ts" /> 
    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    define(['ClassA', 'ClassB'], 
        function (classA, classB) 
        { 
         var aa : IA = new classA.ClassA(); 
         var bb : IB = new classB.ClassB(aa); 
    
         bb.funcB(); 
         aa._classB.funcB(); 
         bb._classA.funcA(); 
         aa.funcA(); 
        }); 
    

和生成的JS代码:

  • 文件ClassA的。JS

    define(["require", "exports"], function(require, exports) { 
        var ClassA = (function() { 
         function ClassA(classB) { 
          this._classB = null; 
          this._classB = classB; 
          if (classB) { 
           this._classB._classA = this; 
          } 
          return this; 
         } 
         ClassA.prototype.funcA = function() { 
          console.log('I am ClassA'); 
         }; 
         return ClassA; 
        })(); 
        exports.ClassA = ClassA; 
    }); 
    
  • 文件ClassB.js

    define(["require", "exports"], function(require, exports) { 
        var ClassB = (function() { 
         function ClassB(classA) { 
          this._classA = null; 
          this._classA = classA; 
          if (classA) { 
           this._classA._classB = this; 
          } 
          return this; 
         } 
         ClassB.prototype.funcB = function() { 
          console.log('I am ClassB'); 
         }; 
         return ClassB; 
        })(); 
        exports.ClassB = ClassB; 
    }); 
    
  • 文件MainTest.js

    define(['ClassA', 'ClassB'], function (classA, classB) { 
    
        var aa = new classA.ClassA(); 
        var bb = new classB.ClassB(aa); 
    
        bb.funcB(); 
        aa._classB.funcB(); 
        bb._classA.funcA(); 
        aa.funcA(); 
    
    }); 
    

最后,输出将是:

我ClassB的

我ClassB的

我ClassA的

我ClassA的

1

您应该能够使用的require()同步版本的B模块的访问 “A” 模块:

// B module 
define([ 
    'a', 
    'exports' 
], function (a, exports) { 
    console.log('A:', a); // A, undefined (as I was expecting) 
    exports.A = function() { 
     return require('a'); 
    } 
    ... 
});