关于 javascript:在将 DynamoDb 放入 node.js lambda 后合并异步 http 请求函数的问题

Problems incorporating an async http request function after a DynamoDb put in node.js lambda

我有一个用 node.js 编写的 AWS Lambda 函数,它将产品发布到 DynamoDB 表中。除了调用 db.put 之外,我还需要使用 Slack SDK 发出一个额外的 http 请求。这是我提取的一个示例,我想在 DynamoDB 调用成功后运行它。我在将它与我当前的代码合并时遇到问题,因为该示例是一个异步函数,而我当前的代码没有使用异步/等待模式。

我试图调用的代码写在异步语句中:

1
2
3
4
5
6
7
(async () => {
  // See: https://api.slack.com/methods/chat.postMessage
  const res = await web.chat.postMessage({ channel: conversationId, text: 'Hello there' });

  // `res` contains information about the posted message
  console.log('Message sent: ', res.ts);
})();

下面是我当前的函数 createProduct,它将产品发布到 DynamoDB(我想在数据库调用成功后立即调用上述代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
'use strict';
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });
const uuid = require('uuid/v4');
const { WebClient } = require('@slack/web-api');
const productsTable = process.env.PRODUCTS_TABLE;
const token = process.env.SLACK_TOKEN;
const web = new WebClient(token);
const conversationId = 'C1232456';


    // Create a response
    function response(statusCode, message) {
      return {
        statusCode: statusCode,
        body: JSON.stringify(message)
      };
    }

    // Create a product
    module.exports.createProduct = (event, context, callback) => {
      const reqBody = JSON.parse(event.body);

      const product = {
        id: uuid(),
        createdAt: new Date().toISOString(),
        userId: 1,
        name: reqBody.name,
        price: reqBody.price
      };

      return db
        .put({
          TableName: productsTable,
          Item: product
        })
        .promise()
        .then(() => {
          callback(null, response(201, product));
        })
        .catch((err) => response(null, response(err.statusCode, err)));
    };

您可以使用 Promise,而不是使用 async/await,这需要您将节点运行时升级到 10.x。由于您想在 DDB 调用成功后运行它,您可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
'use strict';
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });
const uuid = require('uuid/v4');
const { WebClient } = require('@slack/web-api');
const productsTable = process.env.PRODUCTS_TABLE;
const token = process.env.SLACK_TOKEN;
const web = new WebClient(token);
const conversationId = 'C1232456';


    // Create a response
    function response(statusCode, message) {
      return {
        statusCode: statusCode,
        body: JSON.stringify(message)
      };
    }

    // Create a product
    module.exports.createProduct = (event, context, callback) => {
      const reqBody = JSON.parse(event.body);

      const product = {
        id: uuid(),
        createdAt: new Date().toISOString(),
        userId: 1,
        name: reqBody.name,
        price: reqBody.price
      };

      return db
        .put({
          TableName: productsTable,
          Item: product
        })
        .promise()
        .then(() => {
          return web.chat.postMessage({ channel: conversationId, text: 'Hello there' });
        })
        .then(() => {
          callback(null, response(201, product));
        })
        .catch((err) => response(null, response(err.statusCode, err)));
    };


我认为您可以在没有等待的情况下在回调之前调用它,并使用 Promise.all

1
callback(null, response(201, product));

不用等待,直接做

1
2
3
4
5
6
const res = web.chat.postMessage({ channel: conversationId, text: 'Hello there' });
Promise.all(res)
  .then(response => {
console.log(response[0])
callback(null, response(201, product));
});