简体   繁体   English

如何命名匿名 function 或 JavaScript 中的快速中间件?

[英]How to name an anonymous function or a express middleware in JavaScript?

Here's the middleware that I use in express:这是我在 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());` 

But my function still appear as anonymous function in profiler: Something like this:但是我的 function 在分析器中仍然显示为匿名 function :像这样:

在此处输入图像描述

A bit of background: We want to see which middleware is causing the high latency, but because the middlewares are anonymous, we can't narrow down the cause in our APM + JS profiler.一点背景知识:我们想看看是哪个中间件导致了高延迟,但由于中间件是匿名的,我们无法在 APM + JS 分析器中缩小原因。 The preceding is just one example;以上只是一个例子; we use approximately 40 middleware packages over which we have no control.我们使用了大约 40 个我们无法控制的中间件包。

That's why I thought passing f() to namedFunction should fix the issue but it wasn't so looking for help on this.这就是为什么我认为将f()传递给namedFunction应该可以解决问题,但它并没有因此寻求帮助。

Other tries till now : As per Jonsharpe's comment I tried:到目前为止的其他尝试:根据 Jonsharpe 的评论,我尝试过:

app.use(function namedFunction() { f()(...arguments) });

But in profiler it still appear as an anonymous function但在探查器中,它仍然显示为匿名 function

While I do not know much about express , I can at least clear up a misconception you have about anonymous functions.虽然我对express了解不多,但我至少可以澄清您对匿名函数的误解。

When you create a function and immediately store it in a variable, the interpreter can implicitly use the name of the variable as the name of the function.当您创建 function 并立即将其存储在变量中时,解释器可以隐式使用变量的名称作为 function 的名称。 That is true of both functions created with the function expression or with the arrow notation.使用function表达式或箭头符号创建的两个函数都是如此。

const foo = () => {};
foo.name; // "foo";

const bar = function () {};
bar.name; // "bar";

But if you create a function and then immediately pass it as an argument or return it, the interpreter cannot give it a name at creation, so it becomes anonymous.但是如果你创建一个 function 然后立即将它作为参数传递或返回它,解释器在创建时不能给它命名,所以它变成匿名的。

So when you did this:所以当你这样做时:

const namedFunction = f();

All you did was store the already-created anonymous function returned by f() inside the variable namedFunction .您所做的只是将f()返回的已创建匿名 function 存储在变量namedFunction中。 You did not actually give it a name.你实际上并没有给它一个名字。 To do that, you would need to do something like so:为此,您需要执行以下操作:

const unnamedFunction = f();
const namedFunction = (...args) => unnamedFunction(...args);

Which simply wraps the unnamed function into a named one.它只是将未命名的 function 包装成一个命名的。

You could also create a variable to store an arrow function before returning it or passing it as a callback.您还可以创建一个变量来存储箭头 function 在返回它或将其作为回调传递之前。

const meaningfulName = () => { ... };
return meaningfulName;

But unless you actually rely on the behavior of arrow functions, I would just use a named function expression in those cases:但除非你真的依赖箭头函数的行为,否则在这些情况下我只会使用一个命名的 function 表达式:

return function meaningfulName () { ... };

You can assign a function a variable like this:您可以为 function 分配如下变量:

const doSomething = function doSomething() {}

If you decide to use the shorthand function, it means you don't need a function name fo rit.如果您决定使用简写 function,这意味着您不需要 function 名称。

In this answer , an example is shown that redefines the name property of a function which is normally read-only.此答案中,显示了一个示例,该示例重新定义了通常为只读的 function 的 name 属性。 This seems to work just fine in v8.这似乎在 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();

When the function is called and its error is logged, you'd get a stack trace like this, as you saw in your profiler, the function has no name:当调用 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)

Rename as per the linked answer:根据链接的答案重命名:

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

It is now named 'someFn' and should show up in your profiler as such.它现在被命名为“someFn”,并且应该显示在您的分析器中。


Note that this answer is better / less hacky in cases where the source can be edited (OP doesn't have control over f() 's content according to a comment).请注意,在可以编辑源的情况下,这个答案更好/更少hacky(根据评论,OP 无法控制f()的内容)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM