简体   繁体   English

如何宣传AWS JavaScript SDK?

[英]How do I promisify the AWS JavaScript SDK?

I want to use the aws-sdk in JavaScript using promises. 我想使用promises在JavaScript中使用aws-sdk。

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
});

AWS JavaScript SDK的2.3.0版本增加了对promises的支持: http//aws.amazon.com/releasenotes/8589740860839559

You can use a promise library that does promisification , eg Bluebird . 您可以使用一个承诺库,做promisification ,如蓝鸟

Here is an example of how to promisify DynamoDB. 以下是如何宣传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. 不是你可以添加Async到任何方法来获得promisified版本。

Way overdue, but there is a aws-sdk-promise npm module that simplifies this. 方式已过期,但有一个aws-sdk-promise npm模块可以简化这一过程。

This just adds a promise() function which can be used like this: 这只是添加了一个promise()函数,可以像这样使用:

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. 编辑 :我写这个答案已经有几年了,但是因为它似乎最近起来了,所以我想我会更新它: aws-sdk-promise被弃用了,而且更新了(就像在最后一对一样) 多年来 )aws-sdk的版本包括内置的promise支持。 The promise implementation to use can be configured through config.setPromisesDependency() . 可以通过config.setPromisesDependency()配置要使用的promise实现。

For example, to have aws-sdk return Q promises, the following configuration can be used: 例如,要让aws-sdk返回Q promise,可以使用以下配置:

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, eg with Q(...) to get Q promises). 然后promise()函数将直接返回Q promises(当使用aws-sdk-promise ,你必须手动包装每个返回的promise,例如使用Q(...)来获得Q promises)。

I believe calls can now be appended with .promise() to promisify the given method. 我相信现在可以使用.promise()来调用调用给定方法的调用。

You can see it start being introduced in 2.6.12 https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md#2612 您可以看到它开始在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/ 您可以在AWS的博客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() ;
};

With async/await I found the following approach to be pretty clean and fixed that same issue for me for DynamoDB. 使用async / await,我发现以下方法非常干净,并为DynamoDB修复了同样的问题。 This works with ElastiCache Redis as well. 这也适用于ElastiCache Redis。 Doesn't require anything that doesn't come with the default lambda image. 不需要默认lambda图像不带的任何内容。

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));
}

Folks, I've not been able to use the Promise.promisifyAll(Object.getPrototypeOf(dynamoDb)); 伙计们,我无法使用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);

CascadeEnergy/aws-promised CascadeEnergy / AWS-承诺

We have an always in progress npm module aws-promised which does the bluebird promisify of each client of the aws-sdk. 我们有一个永远在进行的npm模块aws-promised ,它使aws-sdk的每个客户端的bluebird aws-promised I'm not sure it's preferable to using the aws-sdk-promise module mentioned above, but here it is. 我不确定使用上面提到的aws-sdk-promise模块是否更好,但现在就是这样。

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! 我们需要贡献,我们只花时间宣传我们实际使用的客户,但还有很多事要做,所以请这样做!

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); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM