我正在尝试编写Lambda代码,在该代码中尝试在DynamoDB中输入多个条目,如果失败,则会在SQS中输入错误消息。我正在尝试使用Promises来做到这一点。
我的DDB.js文件
var AWS = require('aws-sdk');
exports.operation = function(ddbEvent) {
var dynamoDB = new AWS.DynamoDB();
var params = {};
var operation = ddbEvent.operation;
switch(operation) {
case 'insert':
case 'modify':
params["Item"] = ddbEvent.entry;
//Fill in params object from ddbEvent;
return dynamoDb.putItem(params, function(err, data) {
//Nothing to do just log
if(err) {
//log error msg
} else {
//log success
}
}).promise();
case 'delete':
//Do nothing operation
return Promise.resolve();
default:
console.warn("unsupported");
}
};
我的SQS.js文件:
var AWS = require('aws-sdk');
exports.sqsOperation = function(message) {
var sqs = new AWS.SQS({
});
var params = {
//Use message to form the body
};
return sqs.sendMessage(params, function(err, data) {
//Nothing to do just log like in DDB.js
}).promise();
};
我的main.js文件(调用了Lambda):
var AWS = require('aws-sdk');
var SQS = require('SQS');
var DDB = require('DDB');
exports.replicate = function(event, context, callback) {
var ddbPromise = [];
var sqsPromise = [];
event.Records.forEach((entry) => {
let p = DDB.operation(entry);
ddbPromise.push(p);
p.then(function(data) {
//write to ddb succssfull;
}).catch(function (err) {
//ddb save failed, try writing to sqs.
let sqsP = SQS.sqsOperation(entry);
sqsPromise.push(sqsP);
sqsP.then(function (data) {
//push to sqs success
}).catch(function (err) {
//push to sqs failed
});
});
});
var ddb_promises_all = Promise.all(ddbPromise);
ddb_promises_all.then(function (data) {
//all entries saved in DDB
callback(null, "success");
}).catch(function (err) {
//Now repeat wait for all sqs promises. If any sqs push failed then
//use callback(new Error("error"));
});
}
可以看出,promise和回调模式混合在一起。我遇到了一个叫做bluebird的图书馆,它可以帮助避免这个问题。那会是更好的方法吗?是否有更好的方法将这些诺言链接起来,因为我觉得将状态保存在数组中似乎是错误的方法,并且如果使用蓝鸟,则强制从回调模式返回诺言将变得更加整洁。
答案 0 :(得分:1)
异步等待救援 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
async function doDBStuff (...)
async function doOtherStuff (...)
async function doSequentially () {
await doDBStuff(...);
await doOtherStuff(...);
}
async function doInParallel () {
await Promise.all([doDBStuff(...), doOtherStuff(...)]);
}
答案 1 :(得分:1)
对于您的情况,我更喜欢以某些方法将其提取
exports.replicate = function(event, context) {
// if possible, use Promise for consistency
return new Promise((resolve, reject) => {
// I feel that using `map` is cleaner than `forEach`
const ddbOperationPromises = event.Records.map(entry => ddbOperation(entry));
return Promise.all(ddbOperationPromises)
.then(data => {
// success
resolve();
})
.catch(err => {
// catch error
})
});
}
function ddbOperation(entry) {
return DDB.operation(entry)
.then((data) => {
// success
})
.catch((err) => {
return sqsOperation(entry);
})
}
function sqsOperation(entry) {
return SQS.sqsOperation(entry)
.then((data) => {
// success
})
.catch((err) => {
// handling err
})
}