繁体   English   中英

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

[英]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.

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