46

我想通过 Promise 在 JavaScript 中使用 aws-sdk。

而不是默认的回调样式:

dynamodb.getItem(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

相反,我想使用承诺风格:

dynamoDb.putItemAsync(params).then(function(data) {
  console.log(data);           // successful response
}).catch(function(error) {
  console.log(err, err.stack); // an error occurred
});
4

8 回答 8

32

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

于 2016-04-01T00:31:05.817 回答
27

我相信现在可以附加调用.promise()来承诺给定的方法。

您可以看到它在 2.6.12 https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md#2612中开始引入

您可以在 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() ;
};
于 2018-04-11T19:17:35.953 回答
25

你可以使用一个promisification的promise 库,例如Bluebird

这是一个如何承诺 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));

不是你可以添加Async任何方法来获得承诺的版本。

于 2014-10-20T21:47:24.233 回答
15

迟到了,但是有一个aws-sdk-promise npm 模块可以简化这一点。

这只是添加了一个 promise() 函数,可以像这样使用:

ddb.getItem(params).promise().then(function(req) {
    var x = req.data.Item.someField;
});

编辑:我写这个答案已经有几年了,但由于它最近似乎得到了投票,我想我会更新它:aws-sdk-promise已弃用,更新的(如过去几年)版本aws-sdk 包含内置的 Promise 支持。要使用的 Promise 实现可以通过config.setPromisesDependency().

例如,要aws-sdk返回Q承诺,可以使用以下配置:

const AWS = require('aws-sdk')
const Q = require('q')

AWS.config.setPromisesDependency(Q.Promise)

然后该promise()函数将Q直接返回 Promise(使用 时aws-sdk-promise,您必须手动包装每个返回的 Promise,例如 withQ(...)以获取QPromise)。

于 2015-09-11T07:26:27.097 回答
7

使用 async/await 我发现以下方法非常干净,并且为我解决了 DynamoDB 的相同问题。这也适用于 ElastiCache Redis。不需要默认 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));
}
于 2018-06-11T03:37:31.587 回答
5

各位,我一直无法使用Promise.promisifyAll(Object.getPrototypeOf(dynamoDb));

但是,以下内容对我有用:

this.DYNAMO = Promise.promisifyAll(new AWS.DynamoDB());
...
return this.DYNAMO.listTablesAsync().then(function (tables) {
    return tables;
});

或者

var AWS = require('aws-sdk');
var S3 = Promise.promisifyAll(new AWS.S3());

return S3.putObjectAsync(params);
于 2015-03-10T20:23:48.193 回答
1

CascadeEnergy/aws-promised

我们有一个始终在进行的 npm 模块aws-promised,它为 aws-sdk 的每个客户端执行 bluebird promisify。我不确定使用aws-sdk-promise上面提到的模块是否更可取,但就是这样。

我们需要贡献,我们只是花时间承诺我们实际使用的客户,但还有很多事情要做,所以请去做!

于 2015-10-17T04:46:26.100 回答
0

这个解决方案最适合我:

// 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); });
于 2019-07-11T08:17:56.780 回答