【问题标题】:How to pass parameters to function without calling function?如何在不调用函数的情况下将参数传递给函数?
【发布时间】:2020-09-10 22:25:29
【问题描述】:

我正在尝试找到一种方法来获取需要参数的函数,而无需实际调用该函数。

当前损坏的代码示例:

const _validations = {
  userID: (req) => check('userID').isString().isUUID('4').run(req),
};

async function (req, res, next) {
  const allReqFields = { ...req.body, ...req.params, ...req.query };

  const fieldsFound = [];
  for (let key of Object.keys(allReqFields)) {
    if (_.has(_validations, key)) {
      fieldsFound.push(_validations[key](req));
    }
  }

  await Promise.all(fieldsFound);

  return next();
},
  function (req, res, next) {
    const errors = validationResult(req);

    if (errors.isEmpty()) {
//ALWAYS HITS HERE
      return next();
    }else{}
}

有效但我不想要的代码示例:

const _validations = {
  userID: (req) => check('userID').isString().isUUID('4').run(req),
};

async function (req, res, next) {
  const allReqFields = { ...req.body, ...req.params, ...req.query };

  for (let key of Object.keys(allReqFields)) {
    if (_.has(_validations, key)) {
      await _validations[key](req);
    }
  }


  return next();
},
  function (req, res, next) {
    const errors = validationResult(req);

    if (errors.isEmpty()) {
//Correctly hits here
      return next();
    }else{
//Correctly hits here
    }
}

在某些情况下:

函数(req) => check('userID').isString().isUUID('4').run(req),返回一个promise。

_validations 对象内将会有更多的键/值。

_validations 中的每个函数都需要将 req 传递给它。

最终目标是运行所有这些异步函数,同时将 req 传递给它们。

我现在遇到的问题是fieldsFound.push(_validations[key](req)); 正在推动一个承诺,而不是我稍后调用的函数。这意味着fieldsFound 是一组未解决的承诺

有什么想法吗?谢谢!

【问题讨论】:

  • 我真的不明白你在做什么。你能解释一下“最终目标是运行所有这些异步函数,同时将 req 传递给它们。”换个说法?
  • @SteveBennett 我继续添加我遇到的问题。这有帮助吗?
  • 为什么不fieldsFound.push(_validations[key])

标签: javascript node.js asynchronous promise async-await


【解决方案1】:
const _validations = {
  userID: () => check('userID').isString().isUUID('4'),
};

然后你推送函数而不调用它们:

fieldsFound.push(_validations[key]);

最后只需用req 调用每一个并等待返回的承诺:

await Promise.all(fieldsFound.map(func => func().run(req));

【讨论】:

  • 不在范围内。我继续更新我的帖子!
  • @DanMossa 你不能在最后运行.run(req) 吗?
  • 说更多?我会把.run(req) 放在哪里?
  • 我不想要 foreach,否则我只会成为 await _validations[key](req); 。我希望这些都被一次性解雇。
  • 这就是你想要达到的目标吗? await Promise.all(fieldsFound.map(func => func().run(req));
【解决方案2】:

您可以使用函数柯里化。

柯里化是函数式编程中的一个过程,我们可以在其中转换一个函数 将多个参数放入一系列嵌套函数中。它返回一个新函数 期望下一个内联参数。

将你的函数转换成这样的东西。

const _validations = {
  userID: (req) => () => check('userID').isString().isUUID('4').run(req),
};

因此您可以稍后调用该函数。

【讨论】:

  • 有趣!以前从未听说过。我更新了我的代码,但这似乎不起作用?
  • 出了什么问题?
  • 当我使用单独的等待执行此操作时,该函数被正确调用,因为还有另一行检查是否有错误并且没有被调用。我将更新我的原始帖子以进行解释
  • 正如您在问题中提到的,使用上述方法可以将函数推送到数组。例如:fieldsFound.push(_validations[key](req));。因此,您可以稍后使用之前传递的 req 调用这些函数。
猜你喜欢
  • 2021-09-14
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多