我有以下代码可行。我开始使用Bluebird宣传它,但是,我不确定如何宣传消息数组的处理。
var s3 = new AWS.S3();
var sqs = new AWS.SQS();
// This notification call is triggered by the latest message but there may
// be earlier unprocessed messages. So, we request the maximum number of
// messages (10) from the queue and process and then remove from the queue
// all of them.
sqs.receiveMessage({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
WaitTimeSeconds: 20, // to enable long polling, which polls all servers for any unprocessed SQS messages
VisibilityTimeout: 120, // without this longpolling didn't work.
MaxNumberOfMessages: 10
}, function(err, data) {
if (err) {
console.error('SQS receiveMessage failed: ', err, err.stack);
return res.status(400).json({
success: false
});
} else {
var messages = data.Messages;
messages.forEach(function(message) {
var body = JSON.parse(message.Body);
var sesMsg = JSON.parse(body.Message);
s3.getObject({
Bucket: sesMsg.receipt.action.bucketName,
Key: sesMsg.receipt.action.objectKey
}, function(err, data2) {
if (err) {
console.error('S3 getObject failed: ', err, err.stack);
} else {
sqs.deleteMessage({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
ReceiptHandle: message.ReceiptHandle
}, function(err, data) {
if (err) {
console.error('SQS deleteMessage failed: ', err, err.stack);
}
});
}
});
});
}
});
这是我尝试宣传上述代码:
var Promise = require('bluebird');
var s3 = new AWS.S3();
var sqs = new AWS.SQS();
Promise.promisifyAll(Object.getPrototypeOf(s3));
Promise.promisifyAll(Object.getPrototypeOf(sqs));
sqs.receiveMessageAsync({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
WaitTimeSeconds: 20, // to enable long polling, which polls all servers for any unprocessed SQS messages
VisibilityTimeout: 120, // without this longpolling didn't work.
MaxNumberOfMessages: 10
}).then(function(data) {
var messages = data.Messages;
messages.forEach(function(message) {
var body = JSON.parse(message.Body);
var sesMsg = JSON.parse(body.Message);
s3.getObjectAsync({
Bucket: sesMsg.receipt.action.bucketName,
Key: sesMsg.receipt.action.objectKey
}).then(function(data2) {
return sqs.deleteMessageAsync({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
ReceiptHandle: message.ReceiptHandle
}).catch(function(err) {
console.log('SQS deleteMessage failed: ', err, err.stack);
});
}).catch(function(err) {
console.log('S3 getObject failed: ', err, err.stack);
});
});
}).catch(function(err) {
notifyAdmin('SQS receiveMessage failed: ', err, err.stack);
});
我猜这不是使用Promise的最佳方式。我特别好奇是否有更好的方法来处理forEach循环,类似于Bluebird主页中的以下示例:
mongoClient.connectAsync('mongodb://localhost:27017/mydb')
.then(function(db) {
return db.collection('content').findAsync({})
})
.then(function(cursor) {
return cursor.toArrayAsync();
})
.then(function(content) {
res.status(200).json(content);
})
.catch(function(err) {
throw err;
});
那么,我如何使用Bluebird最好地宣传顶部的代码片段?
答案 0 :(得分:2)
在forEach循环中,你的then()函数打破了链,你创建了promises但是你没有“等待”它们。通常的方法是将所有promises存储在数组中并使用Promise.all()。所以使用你的代码:
sqs.receiveMessageAsync({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
WaitTimeSeconds: 20, // to enable long polling, which polls all servers for any unprocessed SQS messages
VisibilityTimeout: 120, // without this longpolling didn't work.
MaxNumberOfMessages: 10
}).then(function(data) {
var messages = data.Messages;
var promises = [];
messages.forEach(function(message) {
var body = JSON.parse(message.Body);
var sesMsg = JSON.parse(body.Message);
var promise = s3.getObjectAsync({
Bucket: sesMsg.receipt.action.bucketName,
Key: sesMsg.receipt.action.objectKey
}).then(function(data2) {
return sqs.deleteMessageAsync({
QueueUrl: settings.sqsQueueUrl[prdOrDev],
/* required */
ReceiptHandle: message.ReceiptHandle
}).catch(function(err) {
console.log('SQS deleteMessage failed: ', err, err.stack);
});
}).catch(function(err) {
console.log('S3 getObject failed: ', err, err.stack);
});
promises.push(promise);
});
return Promise.all(promises);
}).then(function(result) {
console.log('all done');
}).catch(function(err) {
notifyAdmin('SQS receiveMessage failed: ', err, err.stack);
});
您还可以将promisify代码简化为:
var s3 = Promise.promisifyAll(new AWS.S3());
var sqs = Promise.promisifyAll(new AWS.SQS());