【问题标题】:How to dynamically add function objects to an object function map如何将函数对象动态添加到对象函数映射中
【发布时间】:2020-06-12 14:19:06
【问题描述】:

嘿,StackOverflow 世界的人们!感谢您帮助我解决我的问题,如果这个问题有点冗长,我深表歉意。我只想弄清楚我正在处理的所有细节和限制。我发现了一些其他相关的问题,但对于如何解决我的具体问题并没有什么非常清楚的,除非我遗漏了一些东西。相关问题:[1,2]

问题设置:

这就是我所拥有的以及它是如何工作的,我的问题将是关于我遇到的问题 我有一个用命名函数填充的对象。对象映射的目的是包含来自多个文件的许多函数调用。我将每个函数称为“业务规则”,它们通常是非常小的函数,它们执行具有明确定义的输入和输出的单一操作。它还可以让我将函数调用顺序链接起来,functionCall1 的输出变成functionCall2 的输入。

到目前为止,我的所有业务规则定义都位于一组文件中,这些文件位于名为“Framework”的子文件夹中,但我现在要做的是允许“客户端”定义自己的业务规则在他们自己的文件和他们自己的函数调用对象映射。我想做的是将所有函数调用添加到单个共享数据存储中。

我试图避免做的事情: 我不是试图序列化函数调用,也不是试图利用 JS 的“评估”功能。我以前尝试过使用它,但它变得非常混乱! 此外,我不想声明“类”对象或使用“this”关键字,原因如下: 10-most-common-javascript-mistakes

什么是有效的: (注意:大大简化,因为我目前有数百个“业务规则”)

// rulesLibrary.js

import * as stringParsing from './Rules/stringParsing';

export const rulesLibrary = {
  ['Echo']: (inputData, inputMetaData) => (inputData, inputMetaData),

  // Business Rules
  // ********************************
  // StringParsing rules in order
  // ********************************
  ['stringToBoolean']: (inputData, inputMetaData) => stringParsing.stringToBoolean(inputData, inputMetaData),
  ['stringToDataType']: (inputData, inputMetaData) => stringParsing.stringToDataType(inputData, inputMetaData),
}

// stringParsing.js

export const stringToBoolean = function(inputData, inputMetaData) {
  var returnData;
  // Function Body...
  return returnData;
};

export const stringToDataType = function(inputData, inputMetaData) {
  var returnData;
  // Function Body...
  return returnData;
};

// ruleBroker.js

import * as rules from './rulesLibrary';

export const processRules = function(inputData, inputMetaData, rulesToExecute) {
  var returnData = inputData;
  for (var rule in rulesToExecute) {
    if (rulesToExecute.hasOwnProperty(rule)) {
      var key = rule;
      var value = rulesToExecute[key];
      returnData = rules.rulesLibrary[value](returnData, inputMetaData);
    }
  }
  return returnData;
};

您可以在上面的代码中看到rulesLibrary 正在定义对象rulesLibrary = {}; 中的函数,该对象也已导出。然后在ruleBroker 中调用相关函数: rules.rulesLibrary[value](returnData, inputMetaData)....这很好用。

我的目标

我的目标是将所有这些functionName: functionCall 存储在rules.rulesLibrary 上,而不是将它们存储在我称为"D" 的单例数据存储对象上。

这里是“D”的定义:

// 数据.js

export var data = {};

我的尝试 - 尝试 1

我首先尝试将rules.rulesLibrary 中的所有内容从rulesLibrary.js 直接分配给"D",就像在ruleBroker.js 文件中一样:

// NOTE: I am actually doing this inside a function so I can boot-strap the rules.rulesLibrary into `D`, before the application begins going about the business of calling business rules via the ruleBroker.

import * as rules from './rulesLibrary';
var D = require('../Resources/data');

D['BusinessRules'] = {};
D['BusinessRules'] = rules.rulesLibrary;

这没有用,尝试console.log(JSON.stringify(D)); 只是给了我回复:

D{BusinessRules} = {};

我的尝试——尝试 2

所以我想也许我应该尝试直接在"D" 上定义名为函数调用的业务规则映射,就像在rulesLibrary.js 文件中一样:

// 注意:出于与上述相同的原因,我再次在引导函数中执行所有这些操作。

export const initRulesLibrary = function() {
  D['BusinessRules'] = {};
  D['BusinessRules'] = {
    ['Echo']: (inputData, inputMetaData) => (inputData, inputMetaData),

    // Business Rules
    // ********************************
    // StringParsing rules in order
    // ********************************
    ['stringToBoolean']: (inputData, inputMetaData) => stringParsing.stringToBoolean(inputData, inputMetaData),
    ['stringToDataType']: (inputData, inputMetaData) => stringParsing.stringToDataType(inputData, inputMetaData),
  }
};

我再次得到同样的东西,D 的内容是:D{BusinessRules} = {}

也许console.logJSON.stringify 组合不适用于函数对象? 但是话又说回来,我确实有返回函数对象的规则,并且我过去能够使用相同的代码对这些函数对象进行字符串化。当然它是一个函数对象,所以我不希望它在字符串化时看起来很漂亮,但这不是重点。关键应该是函数对象存在于“D”上,但显然不存在,我在这里遗漏了什么?如何将所有函数对象映射到“D”上,以便向其添加/合并更多函数对象定义?

最终这就是我想要做的:

function addClientRules(clientRules) {
  Object.assign(D['BusinessRules'], clientRules['BusinessRules']);
};

这样D 现在包含所有系统定义的业务规则和所有客户端定义的业务规则。然后在ruleBroker 中,我会调用任何这样的业务规则:

export const processRules = function(inputData, inputMetaData, rulesToExecute) {
  var returnData = inputData;
  for (var rule in rulesToExecute) {
    if (rulesToExecute.hasOwnProperty(rule)) {
      var key = rule;
      var value = rulesToExecute[key];
      // OLD WAY:
      // returnData = rules.rulesLibrary[value](returnData, inputMetaData);
      // NEW WAY:
      returnData = D['BusinessRules'][value](returnData, inputMetaData);
    }
  }
  return returnData;
};

有什么想法吗?想法?编辑?咆哮?我至少在正确的轨道上吗?

再次感谢您的帮助!希望这对其他人也有帮助! :-D

【问题讨论】:

    标签: javascript node.js function dictionary ecmascript-6


    【解决方案1】:

    事实证明,我一开始就做的一切都是正确的。只是 console.logJSON.stringify 不能很好地与函数的对象映射配合使用。

    函数映射确实包含函数调用,只是不要指望您的console.log 即使使用JSON.stringify 以任何方式转储该数据。您必须继续进行调用,就好像它在那里一样,并通过将控制台日志放入调用规则的函数中并另外将控制台日志放入要执行的规则中来验证执行是否成功。

    它确实有效,而且它真的很酷!

    我希望这可以帮助其他人,如果您有任何其他问题和/或我是否可以提供其他解决方案详细信息,请发表评论。

    成功执行日志:

    c.ccustomEcho resolves as: customEcho
    BEGIN warden.executeBusinessRule function
    businessRule is: customEcho
    ruleInput is: Calling Custom Echo from application
    ruleMetaData is: Calling Custom Echo from application
    BEGIN ruleBroker.processRules function
    inputData is: "Calling Custom Echo from application"
    inputMetaData is: "something-nothing"
    rulesToExecute are: {"0":"customEcho"}
    BEGIN clientStringParsing.customEcho function
    inputData is: Calling Custom Echo from application
    inputMetaData is: something-nothing
    returnData is: Calling Custom Echo from application clientStringParsing.customEcho
    END clientStringParsing.customEcho function
    returnData is: "Calling Custom Echo from application clientStringParsing.customEcho"
    END ruleBroker.processRules function
    returnData is: Calling Custom Echo from application clientStringParsing.customEcho
    END warden.executeBusinessRule function
    

    干杯

    ~赛斯

    【讨论】:

      猜你喜欢
      • 2012-08-24
      • 1970-01-01
      • 2022-12-05
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2014-12-18
      • 2019-03-02
      相关资源
      最近更新 更多