【问题标题】:If a nodejs module exports an object to two other modules, do changes made to that object in one downstream module propagate to the other?如果一个 nodejs 模块将一个对象导出到其他两个模块,那么在一个下游模块中对该对象所做的更改会传播到另一个模块吗?
【发布时间】:2013-06-05 10:16:52
【问题描述】:

我最初在 nodejs 中有一个工作应用程序,它的所有代码都在一个文件中,使用构造函数和 IIFE 分割成离散的块。为了提供合理的解耦和分离,我一直在尝试重构程序,以便每个块都存在于不同的文件中,但我遇到了问题。

程序分为三个核心块:

初始化连接到 Redis 并返回一个 redis 客户端和 dataStore 对象的数据存储构造函数。

function CreateDataStore(storePort, storeUrl, passwd) {
    var client
    ,   datastore;

    //create the redis client
    //create the datastore

    //exports
    return {
        "redisClient": client,
        "dataObject": createSiteUpdater("")
    };
}

var dataStore = CreateDataStore("xxxx","xxxx","xxxx");
var client = dataStore.redisClient;
var testResults = dataStore.dataObject;

一个网络爬虫构造器,它使用redis客户端并将数据存储在数据存储对象中。

function CreateWebCrawler(){
    //do some stuff
    //initialise robots.txt parser

    return function() {
    //crawl a page
    //add page data to testResults object
    }
}

读取相同数据存储对象并将数据发送到前端客户端的网络服务器构造函数。

function CreateWebServer() {
    //do some stuff
    //initialise an express webserver
    //initialise socket.io
    //send testResults object out over a socket.
}

当它们在同一个文件中时,这一切都很好,但现在我想将它们重构为三个单独的文件,我对它们将如何相互交谈感到困惑。

在新架构下,网络爬虫模块和网络服务器模块都“需要”数据存储模块,该模块导出一个 dataStore 对象。我需要做的是让网络爬虫模块对其数据存储对象所做的任何更改都复制到网络服务器模块可用的数据存储对象版本中。

我已经尝试查看所有 nodejs 文档,并且还进行了很多谷歌搜索,但我无法确定一个由 commonjs 模块的导出语句返回的对象是否相同当对象分别返回到依赖关系图上方的两个不同的其他模块时,堆上的对象。如果这是真的,谁能向我解释一下,最好为我提供一个指向正确文档的链接以正确理解行为?

【问题讨论】:

    标签: javascript node.js refactoring commonjs


    【解决方案1】:

    这是我的做法:

    var datastore = {};
    module.exports = datastore;
    var redis = require('redis');
    
    var client = '';
    var testResults = '';
    
    datastore.CreateDataStore = function(storePort, storeUrl, passwd) {
        client = redis.createClient(storePort,storeUrl);
        redisClient.auth(passwd, function() {
            console.log("redisAuth Connected!");
        });
        testResults = createSiteUpdater("");
    }
    
    datastore.setdata = function(data, callback){
        client.set(data.key, data.value, callback);
    }
    

    第二个功能是我的数据库的访问器功能。不确定这是不是最好的方法,但如果我需要并且应该保存对数据存储对象的任何更改,我可以轻松地换出不同的数据库。与其需要多个模块,不如传递单个对象

    这是一个更完整的示例,其中包含我编写的帐户管理器模块的多个数据库:

    https://github.com/hortinstein/accountManager/tree/master/databaseMiddleware

    【讨论】:

    • 为了清楚起见,您建议在程序的顶层需要数据存储模块,然后将该模块返回的数据存储对象作为显式参数传递给需要它的所有其他模块自己需要表达式的一部分?
    • 我已经完成了上述操作,将数据存储对象作为参数传递给每个需要它的函数。感觉有点凌乱和骇人听闻,尤其是当我将对象传递到调用堆栈的三层时,中间两层不使用它,但底层使用它。但是它有效。
    • 是的,我很高兴它有所帮助。我玩弄了其他一些方法来做到这一点。花了一点时间来适应它,但是您可以重新设计您的代码以使其更清晰。修改传入的对象不会传播到根 obj。如果您需要这些更改,请使用 api 进行通信。
    • 还阅读了这些已接受的答案:stackoverflow.com/questions/10199622/… stackoverflow.com/questions/5608685/… 两者都是清晰明确的答案。 Dominic 是一位 JS 大师
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2019-06-14
    • 2022-01-08
    相关资源
    最近更新 更多