首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >兰博达没有履行所有的承诺

兰博达没有履行所有的承诺
EN

Stack Overflow用户
提问于 2020-08-27 18:05:03
回答 1查看 237关注 0票数 0

我的兰卜达函数为Pets预呈现一个反应用户界面.它由API网关端点调用。我正在从cra-无服务器项目中调整这个项目。我使用的NodeJS服务器框架是Koa。我创建了一个异步handler函数来响应客户端请求。它做了三件事:

  1. 从Pet获取数据并填充getCatsResponse
  2. 使用getCatsResponse对象呈现UI。
  3. 将cat项存储在DynamoDB表中以供进一步处理。

我注意到,这使得我的请求需要很长时间才能得到答复,我想这个问题有点开放,但我希望得到以下三点的澄清:

  1. 为什么当我从由Promise.all()函数创建的Promise列表中删除Promise时,没有将这些项插入到表中呢?
    1. 我认为,因为它是一个异步函数调用,所以请求已经发送,不需要处理响应。我误会什么了?

  2. 假设我需要等待所有的Promise来解决,我应该把这个责任委托给另一个Lambda函数吗?
    1. 如果是这样的话,我可以从这个Lambda调用这个Lambda,然后忘记它(不需要await来解决它),对吗?

  3. 当我设置ctx.body时,这个响应只在Lambda到达函数结束时发送,对吗?
代码语言:javascript
运行
复制
import koa from 'koa'
import http from 'koa-route'
import serve from 'koa-static'

import App from '../src/App'
import { paths } from './config'
import { render } from './lib/render'
import AWS from 'aws-sdk'
import GetCatsResponse from '../typings/GetCatsResponse'

import fetch from 'node-fetch';
import { Cat } from '../typings/Cat'

export const Router = new koa()
const DynamoDB: AWS.DynamoDB = new AWS.DynamoDB();

const handler = async (ctx: koa.Context) => {

  // Try Pet API
  let url = 'https://api.pets.com/v2/cats'
  let getCatsResponse: GetCatsResponse = Object.create(GetCatsResponse);
  await fetch(url).then((response: any) => response.json().then((jsonData: any) => {
    getCatsResponse = jsonData;
  }));
  console.log(getCatsResponse);

  // Render response body 
  ctx.body = render(getCatsResponse, App, ctx.request.path)

  // Enter item into DynamoDB
  return Promise.all(getCatsResponse.items.map((catResponse) => {
    const input: AWS.DynamoDB.PutItemInput = Cat.toDynamoDBTableItemInput(catResponse)
    console.log(input);
    return DynamoDB.putItem(input).promise()
      .then(() => {
        console.log('Inserted cat ID ' + catResponse.cat_id.toString());
      })
      .catch((err) => {
        console.error(err);
      });
  }))

}

Router.use(http.get('/', handler))
Router.use(http.get('/index.html', handler))

Router.use(serve(paths.assets))

Router.use(http.get('*', handler))
EN

回答 1

Stack Overflow用户

发布于 2020-08-27 20:22:43

  1. 因为lambda的工作原理:当它到达终点时,它不仅返回您想要返回的任何内容,还会杀死进程。因此,如果这种情况发生得太快,那么您的调用甚至都没有足够的时间在被杀死之前完成,并且没有在DB中创建这些项。
  2. 是的,但你没有正当理由增加复杂性。当然,您可以调用另一个lambda (例如使用invokeAsync ),但是您将遇到与上面完全相同的问题。而且,对于这样简单的操作,DynamoDB非常(读:非常)快,可能比调用lambda还要快。 然而,如果你关心速度,如果你需要写几个项目,你可能要做的不是多次调用putItem,而是调用batchWriteItem,允许你在一次调用中最多写25项:所以,与25项的网络延迟往返25次相比,您实际上只有1次调用,同时写入25项:https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#batchWriteItem-property
  3. 不熟悉这个特殊的设置,一般也不太熟悉,所以我不确定render通常做什么,或者它在Lambda上是如何表现的。但是,如果您担心呈现会“停止”所发生的操作,则可以执行类似以下操作的操作,这样做的额外好处是按照操作的顺序(get the cats, THEN write them to DB, THEN return the body)更显化。
代码语言:javascript
运行
复制
// Try Pet API
await fetch(url)...

// Enter item into DynamoDB
await Promise.all(...)

// Render response body 
ctx.body = render(getCatsResponse, App, ctx.request.path)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63621830

复制
相关文章

相似问题

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