从RequireJS开始,模块之间的通信

时间:2012-07-16 05:15:29

标签: javascript module requirejs mediator

我是一名ActionScript 3开发人员,他正在构建一个大型JavaScript应用程序。 所以我理解模块并理解AMD是一个很好用的模式。我读了一下RequireJS并实现了它。但是,我仍然不明白的是如何实现跨模块通信。我明白应该有某种调解员...... 我阅读文章和帖子,仍然无法理解如何简单地实现它。 这是我的代码,简化:

main.js

require(["Player", "AssetsManager"], function (player, manager) {
    player.loadXML();
});

Player.js

define(function () {
    function parseXml(xml)
    {
        // NOW HERE IS THE PROBLEM -- how do I call AssetsManager from here???

        AssetsManager.queueDownload($(xml).find("prop").text());
    }

    return {
        loadXML: function () {
            //FUNCTION TO LOAD THE XML HERE, WHEN LOADED CALL parseXml(xml)
        }

    }

});

AssetsManager.js

define(function () {
    var arrDownloadQueue = [];

    return {
        queueDownload: function(path) {
            arrDownloadQueue.push(path);
        }
    }
});

任何“为傻瓜”帮助将不胜感激:) 谢谢。

2 个答案:

答案 0 :(得分:1)

要从define()的其他模块加载模块,您只需将第一个参数设置为数组,并在其中包含模块名称。我们可以说,在您的代码中,您希望将Player.js加载到AssetsManager.js,您只需在数组中包含字符串Player

这是可能的,因为define的抽象实现等同于require,只是传递给define的回调期望返回一个值,并且它将添加一个“模块”到您可以加载的依赖项列表。

<强> AssetsManager.js

define(['Player'], function (player) {
    //... Your code.
});

但是,如果我可以添加它,我个人更喜欢在传递给require的回调中使用define来获取要加载的依赖项,而不是将参数传递给回调。

所以这是我的建议:

define(['Player'], function () {
    var player = require('Player');
});

这是因为它更符合CommonJS

这就是main.js格式化为更适合CommonJS的方式:

require(["Player", "AssetsManager"], function () {
    var player = require('Player');
    var manager = require('AssetsManager');
    player.loadXML();
});

但CommonJS的做事方式只是个人偏好。我的理由是,您在数组中输入依赖项名称的顺序可能随时发生变化,我不希望必须同时遍历数组和参数列表。

我的另一个理由(虽然,它只是迂腐),是我来自Node.js的世界,其中模块通过require()加载。

但这取决于你。

答案 1 :(得分:0)

(这将是对skizeey答案的回复,但我没有足够的声誉)

在不通过require引入Player的AssetManager依赖性的情况下解决此问题的另一种方法是传递main.js已经存在的AssetManager实例。实现此目的的一种方法可能是使Player的loadXML函数接受一个AssetManager参数,然后将该参数传递给parseXml,然后parseXml使用它。另一种方法可能是Player有一个变量来保存一个由parseXml读取的AssetManager。它可以直接设置,也可以使用在变量中存储AssetManager的函数,称为setAssetManager。后一种方法有一个额外的考虑因素 - 然后你需要处理在调用loadXml之前未设置该变量的情况。这个概念通常被称为“依赖注入”。

要明确我不建议使用AMD加载它。我只是想为您提供更多选择;也许这种技术在解决另一个问题时可能会让你更方便,或者可能会帮助别人。 :)