Reputation: 1021
promise() does in AWS lambda here.
I want to send a signal immediately after the file is stored in s3. I'm wondering what .promise() does here. (--s3.putObject({}).promise()--)
The timestamp of fetch(send_to_this_url) was observed at almost equal point when the file was seen on s3 storage. Based on this, promise() does not operate asynchronously. Am I getting something wrong here?
Second in the first couple lines, response is returned when the response is ok. However, if it had returned earlier, file would have not been stored in s3, but it has been, so I am wondering what the purpose of the first if(response.ok) is supposed to be.
Please share any ideas with me.!
fetch(url)
.then((response) => {
if (response.ok) {
return response;
}
return Promise.reject(new Error(
`Failed to fetch ${response.url}: ${response.status} ${response.statusText}`));
})
.then(response => response.buffer())
.then((buffer) => {
s3.putObject({
ACL: "public-read",
Bucket: process.env.BUCKET,
Key: key,
Body: buffer
}).promise();
try{
const send_to_this_url = "someurl?key=" + key;
fetch(send_to_this_url);
}catch(e){
callback('error' + e.message);
}
}
)
.then(v => callback(null, v), callback);
Upvotes: 2
Views: 2740
Reputation: 4068
Per: https://aws.amazon.com/blogs/developer/support-for-promises-in-the-sdk/
Instead of using callbacks, the AWS.Request.promise() method provides a way to call a service operation and return a promise to manage asynchronous flow instead of callbacks.
So .promise() method inside the AWS SDK returns a promise which is like it sounds like in real life, a promise to return something. So lets look at your code:
s3.putObject({
ACL: "public-read",
Bucket: process.env.BUCKET,
Key: key,
Body: buffer
}).promise();
This would be the same as writing it in a callback
s3.putObject({
ACL: "public-read",
Bucket: process.env.BUCKET,
Key: key,
Body: buffer
}, function(e, data) {
if (e) {
callback('error' + e.message);
} else {
// do your thing here.
return fetch("someurl?key=" + data.key;);
}
});
Upvotes: 1
Reputation: 35491
The .promise()
in the AWS JavaScript SDK code represents a way to convert a callback-based API to one returning a promise.
This allows you to then await
on it, or call .then
as with any other promise.
You can leverage this in your code by chaining the promise returned from s3.putObject().promise()
as you did with all others:
fetch(url)
.then((response) => {
// ...
})
.then(response => response.buffer())
// make this part of the promise chain
// use the promise returned when putting
// an object to s3
.then((buffer) => s3.putObject({
ACL: "public-read",
Bucket: process.env.BUCKET,
Key: key,
Body: buffer
}).promise()
)
.then(() => {
// this will run if all promises before it in the chain have resolved successfuly
const send_to_this_url = "someurl?key=" + key;
return fetch(send_to_this_url);
})
.then(resultFromFetchSendToThisUrl => {
// ...
})
.catch(() => {
// this will run if any promise in the chain above rejects
// including the one from s3.putObject
})
Maybe using async-await would make the code more readable:
const response = await fetch(url);
if (!response.ok) {
throw new Error(
`Failed to fetch ${response.url}: ${response.status} ${response.statusText}`
)
}
const buffer = await response.buffer();
const result = await s3.putObject({
ACL: "public-read",
Bucket: process.env.BUCKET,
Key: key,
Body: buffer
}).promise()
const send_to_this_url = "someurl?key=" + key;
const resultFromFetchSendToThisUrl = await fetch(send_to_this_url);
Upvotes: 6