Reputation: 1703
Hello Im chaining promises but the results im getting are not what Im expecting
belowe the code:
createFile(event.body)
.then(() => readFile())
.then((data) => uploadToS3(data))
.then(() => deleteTmp())
.catch(err => console.log(err));
and functions:
async function createFile(fileBinary) {
return await fs.writeFile(TMP_FILE, fileBinary, 'binary', (err) => {
if (err) {
throw {error: 'File upload error_stage1'}
}
return;
});
}
async function readFile() {
return await (fs.readFile(TMP_FILE, (err, data) => {
if (err) {
console.log(err)
throw {error: 'File upload error_stage2'}
}
console.log('read file')
return data;
}));
}
async function uploadToS3(data) {
console.log('upload s3')
const uploadParams = {Bucket: myBucket, Key: myKey, Body: data};
return await s3.putObject(uploadParams, function (err, data) {
if (err) {
throw {error: 'File upload error_stage3'}
}
return data;
});
}
async function deleteTmp() {
fs.unlink(TMP_FILE, (err) => {
if (err) {
throw {error: 'File upload error_stage3'}
}
})
}
console.logs:
upload s3
read file
so from the console logs we can see that the function uploads3 gets executed before read file and that is kind of against the chain order. What am I missing here?
Upvotes: 0
Views: 353
Reputation: 22474
Your readFile
function returns a promise that is resolved without waiting for the file to be read, that is because you've used Promise.resolve()
You need to return a new promise that resolves after the file is read. For example:
function readFile() {
return new Promise((resolve, reject) => {
fs.readFile(TMP_FILE, (err, data) => {
if (err) {
console.log(err)
throw {error: 'File upload error_stage2'}
}
console.log('read file')
resolve(data);
})
})
}
In the uploadToS3
you have this return await s2.putObject....
which won't work because s3.putObject
doesn't return a promise. You'll have to do something similar in order to wait for the file to be uploaded:
function uploadToS3(data) {
const uploadParams = {Bucket: myBucket, Key: myKey, Body: data};
return new Promise((resolve, reject) => {
s3.putObject(uploadParams, function (err, data) {
if (err) {
throw {error: 'File upload error_stage3'}
}
resolve(data);
})
});
}
Upvotes: 1
Reputation: 2758
Looks like you are mixing up chaining calls to functions that return Promises, with async functions.
Stick to one of the other and you should be fine.
A: Make all your functions async, and then simply call them sequentially
or
B: Have all your functions return Promises
Upvotes: 0
Reputation: 1402
It looks like ReadFile is returning a promise, which gets executed later while uploadToS3 doesn't return a promise, so it gets executed in the call.
I don't have an environment set up to test it, but maybe you're wanting to do something like this:
createFile(event.body)
.then(() => readFile()
.then((data) => uploadToS3(data))
.then(() => deleteTmp())) // <- close-parenthesis here.
.catch(err => console.log(err));
Upvotes: 2