如何链接从nodejs中的多个文件返回的承诺
How to chain promises returned from multiple files in nodejs
我正在尝试编写 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"));
});
}
可以看出,混合了承诺和回调模式。我遇到了一个名为 bluebird 的库,它可以帮助避免这个问题。那会是更好的方法吗?有没有更好的方法来链接这些承诺,因为我觉得将状态保存在数组中似乎是一种错误的方法,并且如果使用蓝鸟,则强制 return 来自回调模式的承诺会更整洁。
异步等待救援
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(...)]);
}
对于你的情况,我更喜欢用一些方法来提取它们,比如
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
})
}
我正在尝试编写 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"));
});
}
可以看出,混合了承诺和回调模式。我遇到了一个名为 bluebird 的库,它可以帮助避免这个问题。那会是更好的方法吗?有没有更好的方法来链接这些承诺,因为我觉得将状态保存在数组中似乎是一种错误的方法,并且如果使用蓝鸟,则强制 return 来自回调模式的承诺会更整洁。
异步等待救援 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(...)]);
}
对于你的情况,我更喜欢用一些方法来提取它们,比如
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
})
}