[英]How to name an anonymous function or a express middleware in JavaScript?
这是我在 express 中使用的中间件:
const app = express();
const port = 8000;
const f = () => {
return async (req, res, next) => {
await new Promise(resolve => setTimeout(resolve, 3000));
return next();
}
}
const namedFunction = f();
app.use(namedFunction); // earlier I was using `app.use(f());`
但是我的 function 在分析器中仍然显示为匿名 function :像这样:
一点背景知识:我们想看看是哪个中间件导致了高延迟,但由于中间件是匿名的,我们无法在 APM + JS 分析器中缩小原因。 以上只是一个例子; 我们使用了大约 40 个我们无法控制的中间件包。
这就是为什么我认为将f()
传递给namedFunction
应该可以解决问题,但它并没有因此寻求帮助。
到目前为止的其他尝试:根据 Jonsharpe 的评论,我尝试过:
app.use(function namedFunction() { f()(...arguments) });
但在探查器中,它仍然显示为匿名 function
虽然我对express
了解不多,但我至少可以澄清您对匿名函数的误解。
当您创建 function 并立即将其存储在变量中时,解释器可以隐式使用变量的名称作为 function 的名称。 使用function
表达式或箭头符号创建的两个函数都是如此。
const foo = () => {};
foo.name; // "foo";
const bar = function () {};
bar.name; // "bar";
但是如果你创建一个 function 然后立即将它作为参数传递或返回它,解释器在创建时不能给它命名,所以它变成匿名的。
所以当你这样做时:
const namedFunction = f();
您所做的只是将f()
返回的已创建匿名 function 存储在变量namedFunction
中。 你实际上并没有给它一个名字。 为此,您需要执行以下操作:
const unnamedFunction = f();
const namedFunction = (...args) => unnamedFunction(...args);
它只是将未命名的 function 包装成一个命名的。
您还可以创建一个变量来存储箭头 function 在返回它或将其作为回调传递之前。
const meaningfulName = () => { ... };
return meaningfulName;
但除非你真的依赖箭头函数的行为,否则在这些情况下我只会使用一个命名的 function 表达式:
return function meaningfulName () { ... };
您可以为 function 分配如下变量:
const doSomething = function doSomething() {}
如果您决定使用简写 function,这意味着您不需要 function 名称。
在此答案中,显示了一个示例,该示例重新定义了通常为只读的 function 的 name 属性。 这似乎在 v8 中工作得很好。
// Apart from the added error so we can log a stack trace,
// this is unchanged from your example:
const f = () => {
return async (req, res, next) => {
throw new Error("Intentionally cause an error to log the function's name.");
await new Promise(resolve => setTimeout(resolve, 3000));
return next();
}
}
const namedFunction = f();
当调用 function 并记录其错误时,您会得到这样的堆栈跟踪,正如您在分析器中看到的那样,function 没有名称:
namedFunction().catch(console.log);
// Error: Intentionally cause an error to log the function's name.
// at /tmp/namedfn.js:3:19
// at Object.<anonymous> (/tmp/namedfn.js:9:5)
根据链接的答案重命名:
Object.defineProperty(namedFunction, 'name', {value: 'someFn'});
namedFunction().catch(console.log);
// Error: Intentionally cause an error to log the function's name.
// at someFn (/tmp/namedfn.js:3:19)
// at /tmp/namedfn.js:14:9
它现在被命名为“someFn”,并且应该显示在您的分析器中。
请注意,在可以编辑源的情况下,这个答案更好/更少hacky(根据评论,OP 无法控制f()
的内容)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.