在使用requireJs模块循环依赖(Circular Dependencies in module

2019-06-25 21:33发布

读requireJs文档,
在以固定循环依赖,建议使用exports创建一个空的对象是可立即用于由其他模块引用的模块。

我试试这个代码,但它似乎不工作。 怎么了?

PS:
阅读看到输出的注释,
尤其setTimeout调用内部的乙模块。


// 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 () {
    });
}());

Answer 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');
    }
    ...
});


Answer 2:

我经常使用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()
});


Answer 3:

一种选择是不返回模块本身,但实例化模块(在该示例中,将在产生如图打字稿定义, 在底部的构造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的



文章来源: Circular Dependencies in modules using requireJs