首页 > 解决方案 > 我应该如何将三个参数传递给 express/node 箭头函数?

问题描述

我声明我的功能是这样的:

const parseConnections = (connectionsCSVPath, req, res) => { 
     //do a bunch of stuff 
} 

在函数内部,如果我尝试调用 res.locals.something,我会收到一条错误消息“无法读取未定义的本地属性”我尝试了其他几种语法,例如:

const parseConnections = ((connectionsCSVPath, req, res) => { 
     //do a bunch of stuff 
}) 

这个:

const parseConnections = (connectionsCSVPath, (req, res) => { 
     //do a bunch of stuff 
}) 

和这个:

const parseConnections = connectionsCSVPath, (req, res) => { 
     //do a bunch of stuff 
} 

他们都抛出错误。将这 3 个参数传递给函数以便在内部定义所有 3 个参数的正确方法是什么?

编辑*:然后像这样调用该函数:

router.post(
'/upload/engagements/batch', checkIfAuthenticated,
parseConnections('./tmp/connections.csv'), 
parseMessages('./tmp/messages.csv'), (req, res) => { 
    //do a bunch of stuff 
}

标签: node.jsexpressarrow-functions

解决方案


问题不在于(必然)在于您如何定义函数,而在于您如何使用它。

parseConnections('./tmp/connections.csv')立即调用该函数。你只传递一个参数给它,所以reqand reswill be undefined

function foo(a, b, c) {
  console.log('a:', a);
  console.log('b:', b);
  console.log('c:', c);
}

foo('first argument');

但是,不能为 and 传递值reqres因为这些值是由 express 本身创建和传递的。

本质上,您犯了一个错误,即在应该传递它的地方调用函数。期望传递一个或多个函数。但是您正在调用并传递它的返回值,而不是可能是.router.post parseConnectionsundefined

这是一个演示差异的简单示例:

function foo(x) {
  console.log('inside foo', 'x is ', x);
}

// bar expects to be passed a function that it can call
function bar(callback) {
  console.log('bar received:', callback);
  try {
    callback(42);
  } catch(e) {
    console.error(e);
  }
}


// this will work as expected
console.log('Passing a function');
bar(foo); 

// this will error because `bar` doesn't receive a function.
// this is what you are doing
console.log('Calling a function and passing its return value');
bar(foo(21));


解决问题的一种方法是parseConnections 返回一个函数,然后由router.post. 我在这里使用普通的函数声明,这样语法就不会太混乱:

function parseConnections(connectionsCSVPath) {
  return function(req, res) {
     //do a bunch of stuff 
  };
} 

这不需要更改您的router.post呼叫。


另一种解决方案是将函数传递给router.post该调用parseConnections,而不是传递reqand res

router.post(
  '/upload/engagements/batch',
  checkIfAuthenticated,
  (req, res) => parseConnections('./tmp/connections.csv', req, res),
  // alternatively you can use `.bind`:
  // parseConnections.bind(null, './tmp/connections.csv'),
  parseMessages('./tmp/messages.csv'), // <- this is likely wrong as well,
                                       // but I leave this to you to figure out
  (req, res) => { 
    //do a bunch of stuff 
  }
);

推荐阅读