Marouane Amzil
Marouane Amzil

Reputation: 21

how to use .then with async function

I have a code with all the asynchronous functions, I have a problem at the end is that upload must be executed after the cropImg function, I am not allowed to use setTimeout , and .then does not work not

the image crop function needs to save an image that needs to be uploaded to aws.

I prefer not to use await because it causes problems with promise but even with the use of away I have a problem with the uploadFile function like the image does not exist. the problem is with in the end:

Promise.all([image, promise]).then(values => {
             cropImg(values[0], ratio).then(uploadFile('crop.png', bucket, croppedKey));
         }).catch(error => {
             console.log(error)

all the code

    const promiseListObjectsInBucket = function (input) {
        return new Promise((resolve, reject) => {
            s3.listObjects(input, (err, data) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    };
    
    const uploadFile = (filePath, bucketName, keyName) => {
        // Read the file
        const file = fs.readFileSync(filePath);
    
        // Setting up S3 upload parameters
        const uploadParams = {
            Bucket: bucketName, // Bucket into which you want to upload file
            Key: keyName, // Name by which you want to save it
            Body: file // Local file
        };
    
        s3.upload(uploadParams, (err, data) => {
            if (err) {
                console.log('Error', err);
            }
    
            if (data) {
                console.log('Upload Success', data.Location);
            }
        });
    };
    
    const promisegetObject = function (input) {
        return new Promise((resolve, reject) => {
            s3.getObject(input, (err, data) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    };
    
    async function cropImg(image, ratio) {
        const imageJimp = await Jimp.read(image);
        const w = imageJimp.bitmap.width;
        const h = imageJimp.bitmap.height;
        const newW = w * ratio;
        const newX = Math.floor((w - newW) / 2);
        const newH = h * ratio;
        const newY = Math.floor((h - newH) / 2);
        imageJimp.crop(newX, newY, newW, newH).write('crop.png');
    }
    
    function createCropVersion({bucket, originalKey, croppedKey, ratio = 0.5}) {
        const originalObjectParams = {
            Bucket: bucket,
            Key: originalKey
        };
        const bucketParams = {
            Bucket: bucket
        };
        // Check if a cropped version exist
        const promise = promiseListObjectsInBucket(bucketParams).then(data => {
            const files = data.Contents;
            const error = 'cropped version exist';
            for (const file of files) {
                if (file.key === croppedKey) {
                    throw error;
                }
            }
        }).catch(error => {
            console.log(error);
        });
    
        const image = promisegetObject(originalObjectParams).then(data => {
            const originalimg = data.Body;
            return originalimg;
        }).catch(error => {
            console.log(error);
        });
        Promise.all([image, promise]).then(values => {
            cropImg(values[0], ratio).then(uploadFile('crop.png', bucket, croppedKey));
        }).catch(error => {
            console.log(error);
        });
    }

Upvotes: 0

Views: 74

Answers (1)

Barmar
Barmar

Reputation: 781058

You need to wait for .write() to finish. To get a promise from it, you have to call .writeAsync() instead. See the documentation.

    async function cropImg(image, ratio) {
        const imageJimp = await Jimp.read(image);
        const w = imageJimp.bitmap.width;
        const h = imageJimp.bitmap.height;
        const newW = w * ratio;
        const newX = Math.floor((w - newW) / 2);
        const newH = h * ratio;
        const newY = Math.floor((h - newH) / 2);
        await imageJimp.crop(newX, newY, newW, newH).writeAsync('crop.png');
    }

Then you need to pass a callback function to .then() to call uploadFile().

        Promise.all([image, promise]).then(values => {
            cropImg(values[0], ratio).then(() => uploadFile('crop.png', bucket, croppedKey));

Upvotes: 1

Related Questions