即使在承诺中使用箭头函数,打字稿中也未定义“this”

Lea*_*dro 3 node.js typescript

当我收到 'catch' 回调时,'this' 是未定义的,即使使用箭头函数也是如此。有任何想法吗?

private all(req: Request, res: Response): void {
    EntityRepository.getRepositoty(req.params.etName).then(repo => {

        ...

    }).catch((err) => {
        this.handleError(res, err); // here I get undefined.
    });
}
Run Code Online (Sandbox Code Playgroud)

all func 是如何调用的。

它是基于 Express 路由调用的。

bind按照@jfriend00 的建议添加了mathod。

constructor() {
    // Connect to database.
    DataAccess.connect();

    // Starts configuring routes for api
    this.router = Router();

    // Bad request due to absence of entity type.
    this.router.get("/", (req, res) => {
        res.statusCode = 400;
        res.statusMessage = SysMsgs.error.noEntityTypeSpecified.message;
        res.send();
    });

    // Added method 'bind'.
    this.router.get(this.routeBase, this.all.bind(this));
    this.router.get(this.routeBase + "/:id", this.findOne.bind(this));
}
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

使用箭头函数,this将保留它在箭头函数调用之前在作用域中的值。在您的情况下,这意味着它将具有函数this开头的任何值all。因此,该值this取决于all函数的调用方式。

并且,根据this.router.get()您指定this.all为回调的位置,这意味着thisinside ofall将设置为 Express 在调用该回调时设置的任何内容。而且,那就是undefined

您可以使用.bind().

 this.router.get(this.routeBase, this.all.bind(this));
Run Code Online (Sandbox Code Playgroud)

这将确保this.all()运行时设置适当的。然后,您的arrow函数内部all()将使用this.

注意:您将需要.bind()用于您作为回调传递的任何方法,其中您希望this成为回调内的对象。当您传递诸如 之类this.all的东西时, 的值this会丢失,并且只传递对该方法的引用。然后调用者将该方法作为没有对象绑定的普通函数调用。你.bind()过去常常自己控制。 .bind()本质上创建了一个小的存根函数,该函数this通过使用它调用您的方法来重新附加适当的指针。


您还可以为它制作自己的包装箭头函数:

 this.router.get(this.routeBase, (req, res) => this.all(req, res));
Run Code Online (Sandbox Code Playgroud)

正如 Saravana 指出的那样,它将保留 TypeScript 类型检查。