1

我有一个 lambda 函数,它使用 xstate 顺序执行某些任务,其中一个步骤是将数据保存到 dynamo db。但是,只要执行以下行,我的 lambda 就会结束执行。

const response = await new DynamoDB.DocumentClient().put(params).promise();

我的代码:

import {Handler} from "aws-lambda";
import {interpret} from 'xstate';
import { Machine} from "xstate";
import {PutItemInput} from "aws-sdk/clients/dynamodb";
import {DynamoDB} from "aws-sdk";

export const recordProcessor: Handler = async (event) => {
  console.log('records size----->', event.Records.length);
  for (const record of event.Records) {
      const body = JSON.parse(record.body);
      console.log('body ----->', body);

    interpret(Machine({id:'test',
      context:body,
      initial: 'start',
      states:{
        start: {
          invoke: {
            src: context => initiate(context),
            onDone: {
              target: 'success'
            }
          }
        },
        success: {
          type: 'final'
        }
      }
    })).onTransition(state => {
      if (state.changed) {
        console.log('state ----> ', state.value);
      }
    }).onDone(() => console.log('done--->')).start();
  }


  async function initiate(context: any) {
    console.log('DbDynamoImpl ::: insert ::: start :::');
    let params: PutItemInput = {
      TableName: 'test',
      Item: context
    };
    try {
      const response = await new DynamoDB.DocumentClient().put(params).promise();
      console.log('DbDynamoImpl ::: insert ::: response :::', response);
      return true;
    } catch (e) {
      console.log("DynamoDb insert error", e);
      return false;
    }
  }

};
4

3 回答 3

0

将机器解释和交互包装成一个 Promise 允许您等待状态机达到最终状态。

大致是这样的


export const recordProcessor: Handler = async (event) => {
  console.log('records size----->', event.Records.length);
  for (const record of event.Records) {
      const body = JSON.parse(record.body);
      console.log('body ----->', body);
      await setupMachine(...);
...
}

function setupMachine(...){
  return new Promise((resolve, reject) => {
    interpret(Machine({id:'test',
      context:body,
      initial: 'start',
      states:{
        start: {
          invoke: {
            src: context => initiate(context),
            onDone: {
              target: 'success'
            }
          }
        },
        success: {
          type: 'final'
        }
      }
    })).onTransition(state => {
      if (state.changed) {
        console.log('state ----> ', state.value);
      }
    })
     .onDone(() => { console.log('done--->'); return resolve()})
     .onStop(() => reject());
     .start();
   }
  });
}
于 2021-03-03T22:38:08.000 回答
0

你在点击return声明之前解决了 Promise。您可以尝试resolve Promise使用需要返回的值吗?然后它将使用这些值转到 onDone 块。在这里拥有trycatch阻塞也是多余的,因为service它将xstate自动为您处理。

只需在服务调用语句中返回承诺,因为它需要是一个返回 a 的函数Promise

function initiate(context: any) {
  console.log('DbDynamoImpl ::: insert ::: start :::');
  let params: PutItemInput = {
    TableName: 'test',
    Item: context,
  };
  return new DynamoDB.DocumentClient().put(params).promise();
}

然后在你的onDone街区你可以console.log('DbDynamoImpl ::: insert ::: response :::', response);

onDone: {
  target: 'success',
  actions: (ctx, e) => console.log('DbDynamoImpl ::: insert ::: response :::', e),
}

于 2020-04-09T15:24:55.970 回答
-1

添加async到您的功能,然后再次测试。

exports.handler = async (event, context) => {
    return ...
}
于 2020-03-07T14:42:57.983 回答