如何承诺 AWS JavaScript 开发工具包?
Posted
技术标签:
【中文标题】如何承诺 AWS JavaScript 开发工具包?【英文标题】:How do I promisify the AWS JavaScript SDK? 【发布时间】:2014-12-16 00:23:06 【问题描述】:我想通过 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
);
我想使用promise 样式:
dynamoDb.putItemAsync(params).then(function(data)
console.log(data); // successful response
).catch(function(error)
console.log(err, err.stack); // an error occurred
);
【问题讨论】:
那么,你试过bluebird.promisifyAll(dynamodb)
吗?
与蓝鸟var dynamoDb = Promise.promisifyAll(new AWS.DynamoDB());
因为 aws-sdk@^2.3.0 已经支持 promise。注意: aws-sdk@^2.3.0 的 bluebird.promisifyAll 将导致错误 module initialization error: TypeError
【参考方案1】:
这个解决方案最适合我:
// 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); );
【讨论】:
【参考方案2】:使用 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));
【讨论】:
AWS.CognitoIdentityServiceProvider
对我来说非常有用。添加bind
修复了错误TypeError: this.makeRequest is not a function
。
谢谢!你是对的,到目前为止,我已经成功地将这种方法用于每个 AWS 开发工具包服务,只需复制、粘贴、重构!我喜欢将它们包装到迷你库中,以最大限度地提高 Lambda 中主要 index.js 代码的可读性。【参考方案3】:
迟到了,但有一个aws-sdk-promise npm 模块可以简化此操作。
这只是添加了一个 promise() 函数,可以像这样使用:
ddb.getItem(params).promise().then(function(req)
var x = req.data.Item.someField;
);
编辑:我写这个答案已经有几年了,但由于它最近似乎越来越受欢迎,我想我会更新它:aws-sdk-promise
已弃用,并且aws-sdk 的较新(如过去几年)版本包括内置的 Promise 支持。可以通过config.setPromisesDependency()
配置要使用的promise 实现。
例如,要让aws-sdk
返回Q
承诺,可以使用以下配置:
const AWS = require('aws-sdk')
const Q = require('q')
AWS.config.setPromisesDependency(Q.Promise)
然后promise()
函数将直接返回Q
承诺(使用aws-sdk-promise
时,您必须手动包装每个返回的承诺,例如使用Q(...)
来获得Q
承诺)。
【讨论】:
AWS 版本 3 允许模块化使用 AWS 库,而不需要整个 aws-sdk。当没有全局 AWS 配置时,有没有办法将 DynamoDBClient 的 Promise 依赖设置为第三方 Promise?【参考方案4】:我相信现在可以在调用后附加.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() ;
;
【讨论】:
请注意,这只适用于某些功能。来自 AWS Docs:“注意:这目前仅适用于返回 AWS.Request 实例的操作。”【参考方案5】:AWS JavaScript SDK 2.3.0 版本增加了对 Promise 的支持:http://aws.amazon.com/releasenotes/8589740860839559
【讨论】:
不幸的是,Lambda 不支持。 :-( 所以,我一直试图让它在 Lambda 中工作,并刚刚找到您的评论。为什么这在 Lambda 中不起作用?你在哪里找到这些信息的?谢谢! 如果您使用节点 4.3.2,它应该可以在 lambda 下工作,您甚至可以更改 Promise 库。如果您使用的是节点 0.10.x,那么您必须更改 Promise 库,因为它本身不可用。欲了解更多信息,请查看:github.com/aws/aws-sdk-js/blob/… 也许这个答案应该提到如何在 aws-sdk 中启用承诺支持,而不是仅仅链接到概览页面。基本上需要AWS.config.setPromisesDependency(Q.Promise);
来使用Q,并对应于其他promise 实现。更多信息请访问aws.amazon.com/blogs/developer/support-for-promises-in-the-sdk,但请复制内容而不仅仅是链接。【参考方案6】:
CascadeEnergy/aws-promised
我们有一个始终在进行的 npm 模块 aws-promised
,它为 aws-sdk 的每个客户端执行 bluebird promisify。我不确定使用上面提到的aws-sdk-promise
模块是否更可取,但就是这样。
我们需要贡献,我们只是花时间承诺我们实际使用的客户,但还有很多事情要做,所以请去做!
【讨论】:
【参考方案7】:各位,
我一直无法使用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);
【讨论】:
您不想将Promise.promisifyAll
作为构造函数调用。请省略第一个new
【参考方案8】:
您可以使用执行promisification 的承诺库,例如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
添加到任何方法以获取承诺版本。
【讨论】:
对我来说很棒!我正在使用新的 DynamoDB-doc 库。 var docClient = new doc.DynamoDB(); Promise.promisifyAll(Object.getPrototypeOf(docClient));以上是关于如何承诺 AWS JavaScript 开发工具包?的主要内容,如果未能解决你的问题,请参考以下文章
使用字节的 AWS Rekognition JavaScript 开发工具包
如何正确解析 bs-typeahead 的 javascript 承诺
如何在节点 AWS 开发工具包代码中使用 AWS ECS 任务角色