【问题标题】:Arrow function returns an arrow function箭头函数返回一个箭头函数
【发布时间】:2021-07-04 08:15:35
【问题描述】:

我曾经在 JS 中使用箭头函数,但是在尝试解决 ExpressJS 中的异步等待问题时,我在 Google 上搜索并遇到了这个函数:

const asyncHandler = fn => (req, res, next) => {
    return Promise
        .resolve(fn(req, res, next))
        .catch(next);
};

而且这个函数可以这样使用(在 ExpressJS 中):

app.use(asyncHandler(async(req, res, next) => {
    await authenticate(req);
    next();
}));

从代码中我了解到asyncHandler是一个函数,它接收另一个函数(fn),而那个函数(fn)返回另一个函数,并且在那个函数内部,调用fn。

我不明白为什么req、res、next这3个变量没有传递给fn可以用来传递给另一个函数,为什么fn可以返回一个调用fn的函数。

【问题讨论】:

  • asyncHandler 是一个高阶函数,一个中间件“工厂”。
  • 我不明白你在问什么。
  • 嘿,你能澄清一下你问题的最后一段吗?我无法正确理解!
  • @h-sifat 函数 fn 返回另一个函数。并且返回的函数接收 3 个参数 req、res 和 next。但是fn函数没有接收任何参数,它怎么能传递给另一个呢。

标签: javascript arrow-functions


【解决方案1】:

从代码中,我了解到 asyncHandler 是一个函数 接收另一个函数 (fn),并且该函数 (fn) 返回另一个 函数,并在该函数内部调用 fn。

asyncHandler 是一个函数,它有一个参数 fn 并返回一个函数。

参数fn 是一个函数,它具有三个参数reqresnext,并返回一个Promise

asyncHandler 返回的函数也有三个参数reqresnext,并返回一个Promise

asyncHandler 在闭包中捕获fn(通过在.resolve(fn(req, res, next)) 中引用它)。这意味着asyncHandler 返回的函数现在拥有对传递给它的函数的保留引用,并且可以稍后调用它。

所以,asyncHandler 接受一个函数(具有签名(res, req, next) => Promise)并将其包装在一个函数(也具有签名(res, req, next) => Promise)中,该函数返回一个Promise,如果它调用next()失败并将错误传递给错误处理程序(这就是 .catch(next) 所做的)。

它实际上只是节省了一些样板,否则您将在 app.use() 调用 next() 中处理捕获错误。

我不明白为什么 3 个变量 req, res, next 没有传递给 fn 可用于传递给另一个函数以及为什么 fn 可以返回 a 调用 fn 的函数。

它们在.resolve(fn(req, res, next)) 中传递给fn。当所有这些实际运行时,它们会从 ExpressJS 传递到由 asyncHandler 返回的函数中,从那里它们被传递到作为 fn 传入的函数中。

我想这一切都变得令人困惑,因为有很多匿名函数被传递。不确定最令人困惑的部分是箭头函数语法还是闭包或匿名函数。我们可以去掉箭头语法糖:

const verboseAsyncHandler = function(fn) {
    return function(req, res, next) {
        return Promise
            .resolve(fn(req, res, next))
            .catch(next);
    }
}

不确定这是否对您有帮助。

【讨论】:

  • 非常感谢。这是我第一次知道概念闭包。在阅读了它和您的评论之后,现在我可以理解我的问题了。
猜你喜欢
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多