【问题标题】:AWS Lambda with typescript getting Cannot read property of undefined inside async handler带有 typescript 的 AWS Lambda 无法读取异步处理程序中未定义的属性
【发布时间】:2021-06-18 07:51:27
【问题描述】:

Typescript 新手在这里。我正在使用带有类的打字稿来处理 AWS Lambda 函数。我在最后导出一个async 处理程序。当我从 AWS SAM CLI 调用我的函数时,我收到以下错误;

{"errorType":"TypeError","errorMessage":"Cannot read property 'test' of undefined","stack":["TypeError: Cannot read property 'test' of undefined"," at Runtime.handler (/var/task/src/lambda/create-cost-lambda.js:12:56)"," 在 Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]}

create-cost-lambda.ts

class CreateCostLambda {
    private readonly foobarRepository: FoobarRepository;

    constructor() {
        this.foobarRepository = new FoobarRepository();
    }

    async handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
        const result = await this.foobarRepository.test();
        console.log(result);

        return {
            body: JSON.stringify(result),
            statusCode: 200,
        };
    }
}

export const { handler } = new CreateCostLambda();

这是一个非常基本的类,代表一个存储库。

foobar-repository.ts

export class FoobarRepository {
    private readonly awesomeValue: string;

    constructor() {
        this.awesomeValue = 'John Doe';
    }

    async test(): Promise<string> {
        return this.awesomeValue;
    }
}

我几乎可以肯定这是因为我导出处理程序的方式以及aws-sam 在内部运行处理程序的方式。但我可能错了,它可能是我错过的打字稿。如果您需要更多信息,请告诉我,非常感谢您的帮助!

【问题讨论】:

  • async handler(event: APIGatewayProxyEventV2) : Promise&lt;APIGatewayProxyResultV2&gt; 需要是箭头函数。您正在失去功能的上下文。写成handler = async (event: APIGatewayProxyEventV2) : Promise&lt;APIGatewayProxyResultV2&gt; =&gt; {..}
  • @Townsheriff 感谢您的方法。我正在考虑更多的面向对象的实现方式,这在文章blog.10pines.com/2019/07/23/… 中进行了讨论。因此,使用bind 导出处理程序按预期工作。就像是; export const createCostLambda = new CreateCostLambda(); export const handler = createCostLambda.handler.bind(createCostLambda); 对于我的要求,这是一个不好的方法吗?谢谢!
  • 我不知道你为什么想要这样的东西。您需要绑定,否则您将无法访问上下文。我只会使用一个函数 - module.exports.handler = (...) =&gt; {...}。箭头函数将函数绑定到它自己的上下文,因此您可以在类中编写箭头“方法”,它将起作用typescriptlang.org/play?#code/…
  • 谢谢你。我采用了仅使用箭头函数的方法。

标签: node.js typescript aws-lambda es6-promise aws-sam


【解决方案1】:

简短的版本是,如果你从一个类中传递一个函数,它会丢失它对this 的引用。

我会这样解决这个问题:

const createCostLambda = new CreateCostLambda();
export const handler = createCostLambda.handler.bind(createCostLambda);

你也可以问问自己,这需要上课吗?答案是:可能不会。在您的示例中没有任何收获。

const foobarRepository = new FoobarRepository();
export async function handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
   const result = await foobarRepository.test();
   console.log(result);

   return {
     body: JSON.stringify(result),
     statusCode: 200,
   };
}

行数更少,没有不需要的状态。 Javascript 不是 Java =)

【讨论】:

  • 是的,你是对的。我想如果我会使用一个类中的处理程序方法,它会更好地用于测试目的(我是 Java 人:))。所以,我通过导出一个函数来采用这种方法。再次感谢
猜你喜欢
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 2022-01-22
  • 2021-02-16
  • 2021-11-20
  • 2018-03-13
  • 2018-08-30
  • 1970-01-01
相关资源
最近更新 更多