node.js - AWS lambda 实例在 xstate 调用承诺时关闭
问题描述
我有一个 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;
}
}
};
解决方案
将机器解释和交互包装成一个 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();
}
});
}