问题
I want to use the aws-sdk in JavaScript using promises.
Instead of the default callback style:
dynamodb.getItem(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
I instead want to use a promise style:
dynamoDb.putItemAsync(params).then(function(data) {
console.log(data); // successful response
}).catch(function(error) {
console.log(err, err.stack); // an error occurred
});
回答1:
I believe calls can now be appended with .promise()
to promisify the given method.
You can see it start being introduced in 2.6.12 https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md#2612
You can see an example of it's use in AWS' blog https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = async (event) => {
return await lambda.getAccountSettings().promise() ;
};
回答2:
The 2.3.0 release of the AWS JavaScript SDK added support for promises: http://aws.amazon.com/releasenotes/8589740860839559
回答3:
You can use a promise library that does promisification, e.g. Bluebird.
Here is an example of how to promisify DynamoDB.
var Promise = require("bluebird");
var AWS = require('aws-sdk');
var dynamoDbConfig = {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.AWS_REGION
};
var dynamoDb = new AWS.DynamoDB(dynamoDbConfig);
Promise.promisifyAll(Object.getPrototypeOf(dynamoDb));
Not you can add Async
to any method to get the promisified version.
回答4:
Way overdue, but there is a aws-sdk-promise npm module that simplifies this.
This just adds a promise() function which can be used like this:
ddb.getItem(params).promise().then(function(req) {
var x = req.data.Item.someField;
});
EDIT: It's been a few years since I wrote this answer, but since it seems to be getting up-votes lately, I thought I'd update it: aws-sdk-promise
is deprecated, and newer (as in, the last couple of years) versions of aws-sdk includes built-in promise support. The promise implementation to use can be configured through config.setPromisesDependency()
.
For example, to have aws-sdk
return Q
promises, the following configuration can be used:
const AWS = require('aws-sdk')
const Q = require('q')
AWS.config.setPromisesDependency(Q.Promise)
The promise()
function will then return Q
promises directly (when using aws-sdk-promise
, you had to wrap each returned promise manually, e.g. with Q(...)
to get Q
promises).
回答5:
With async/await I found the following approach to be pretty clean and fixed that same issue for me for DynamoDB. This works with ElastiCache Redis as well. Doesn't require anything that doesn't come with the default lambda image.
const {promisify} = require('util');
const AWS = require("aws-sdk");
const dynamoDB = new AWS.DynamoDB.DocumentClient();
const dynamoDBGetAsync = promisify(dynamoDB.get).bind(dynamoDB);
exports.handler = async (event) => {
let userId="123";
let params = {
TableName: "mytable",
Key:{
"PK": "user-"+userId,
"SK": "user-perms-"+userId
}
};
console.log("Getting user permissions from DynamoDB for " + userId + " with parms=" + JSON.stringify(params));
let result= await dynamoDBGetAsync(params);
console.log("Got value: " + JSON.stringify(result));
}
回答6:
Folks,
I've not been able to use the Promise.promisifyAll(Object.getPrototypeOf(dynamoDb));
However, the following worked for me:
this.DYNAMO = Promise.promisifyAll(new AWS.DynamoDB());
...
return this.DYNAMO.listTablesAsync().then(function (tables) {
return tables;
});
or
var AWS = require('aws-sdk');
var S3 = Promise.promisifyAll(new AWS.S3());
return S3.putObjectAsync(params);
回答7:
CascadeEnergy/aws-promised
We have an always in progress npm module aws-promised
which does the bluebird promisify of each client of the aws-sdk. I'm not sure it's preferable to using the aws-sdk-promise
module mentioned above, but here it is.
We need contributions, we've only taken the time to promisify the clients we actually use, but there are many more to do, so please do it!
回答8:
This solution works best for me:
// Create a promise object
var putObjectPromise = s3.putObject({Bucket: 'bucket', Key: 'key'}).promise();
// If successful, do this:
putObjectPromise.then(function(data) {
console.log('PutObject succeeded'); })
// If the promise failed, catch the error:
.catch(function(err) {
console.log(err); });
来源:https://stackoverflow.com/questions/26475486/how-do-i-promisify-the-aws-javascript-sdk