首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何调用Lambda函数,然后使用Serverless返回

如何调用Lambda函数,然后使用Serverless返回
EN

Stack Overflow用户
提问于 2020-09-02 20:44:58
回答 2查看 54关注 0票数 0

我正在使用Serverless部署一个基本的web抓取API。在切换到无服务器设置之前,我测试了抓取代码,我发现根据抓取的特定URL和检索的数据,抓取代码可能需要60秒以上的时间才能完成。

我已在serverless.yml中设置了正确的IAM权限

代码语言:javascript
复制
iamRoleStatements:
  - Effect: Allow
    Action:
      - lambda:InvokeFunction
    Resource: "*"

我还设置了我的两个函数:

代码语言:javascript
复制
functions:
  scrape:
    handler: handler.scrape
    memorySize: 1536MB
  
  triggerScrape:
    handler: handler.triggerScrape
    events:
      - http:
          path: /scrape
          method: get

在我的handler.js

代码语言:javascript
复制
module.exports.triggerScrape = async (event, context) => {
  try {
    const invoke = lambda.invoke({
      FunctionName: 'my-api-v2-dev-scrape',
      InvocationType: 'Event',
      Payload: JSON.stringify({
        link: event.queryStringParameters['link'],
        batchId: event.queryStringParameters['batchId'],
      })
    })

    return {
      statusCode: 202,
      headers: {
        'Access-Control-Allow-Origin': '*'
      },
      body: JSON.stringify({ message: 'Scrape request recieved' })
    }
  } catch (err) {
    console.log(`Invoke error: ${err}`)
  }
}

module.exports.scrape = async (event) => {
  // Lengthy Puppeteer scrape code that gets data and saves it to a database
  // It does not need to return as part of the API call, it just needs to be triggered once
  // and the user will refresh the page later to see the results
}

当我获得/triggerScrape端点时,我得到了202: "Scrape request recieved",但就我所见,scrape函数从未运行过。当我运行serverless logs -f scrape时,什么也没有返回。

有人知道如何检查函数是否实际运行了吗?这与请求的异步性质有关吗?提前感谢您能给出的任何建议。

EN

回答 2

Stack Overflow用户

发布于 2020-09-02 21:36:35

在发送API请求之前,您的处理程序正在返回。您需要在调用lambda.invoke时使用await.promise() (它返回一个promise):

代码语言:javascript
复制
const invoke = await lambda.invoke({
  FunctionName: 'my-api-v2-dev-scrape',
  InvocationType: 'Event',
  Payload: JSON.stringify({
    link: event.queryStringParameters['link'],
    batchId: event.queryStringParameters['batchId'],
  })
}).promise();

或者,您可以传递一个回调函数来调用。

在调试这类问题时,在您期望完成的工作之前和之后添加console.log调用并记录它返回的内容是很有用的。

票数 1
EN

Stack Overflow用户

发布于 2020-09-02 22:30:26

在经历了大量痛苦的试验和错误之后,我终于找到了一个主题的答案:https://stackoverflow.com/a/54126705/3011431

这似乎是唯一对我起作用的事情,尽管围绕它的话题数量似乎所有的事情都可以修复任何给定情况的实现。

我最终将Lambda invoke调用包装在一个Promise中:

代码语言:javascript
复制
module.exports.triggerScrape = async (event) => {
  try {
    await new Promise((resolve, reject) => {
      lambda.invoke({
        FunctionName: 'my-api-v2-dev-scrape',
        InvocationType: 'Event',
        Payload: JSON.stringify({
          link: event.queryStringParameters['link'],
          batchId: event.queryStringParameters['batchId'],
        })
      }, (err, data) => {
        if (err) {
          console.log(err, err.stack)
          reject(err)
        }
        else {
          resolve(data)
        }
      })
    })

    return {
      statusCode: 202,
      headers: {
        'Access-Control-Allow-Origin': '*'
      },
      body: JSON.stringify({ message: 'Audit request recieved' })
    }
  } catch (err) {
    console.log(`Invoke error: ${err}`)
  }
}

最终我得到了202响应,我还看到scrape已经被触发,因为我现在可以看到scrape函数上的日志,而且擦伤的数据也已经成功地推送到我的数据库中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63705824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档