How do I promisify the AWS JavaScript SDK?

主宰稳场 提交于 2019-12-17 18:12:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!