Skip to content
Advertisement

How do I make a function wait for the completion of another function before running

The problem I’m facing is that I want to create a temporary work folder for a certain function to hold its assets and work on them.

So:

await function someFunc() {
    createFolder()
    ...
    makeSomeFiles()
    doOtherStuff()
    ...
    deleteFolder()
}

But the functions that I am using, in node.js, are all async. Creating a folder is fs.mkdir() and deleting a folder is fs.rmdir() and downloading images and saving them is also an async procedure of some kind.

The problem is such: the folder gets created, and deleted, before any of the code in the middle executes. So I get errors from the middle section code that the folder doesn’t exist, because it gets deleted prematurely. How do i make fs.rmdir(), at the end, wait for all the middle code to run first, before deleting the folder.

The specific code is this:

async function run() {
    //GENERATE SESSION ID AND FOLDER
    const sessionID = str.random(50);
    fs.mkdir('images/'+sessionID, (err) => {
        if (err) return err;
    });

    //DOWNLOAD IMAGE
    https.get('https://en.wikipedia.org/wiki/Main_Page#/media/File:RE_Kaja_Kallas.jpg', (file) => {
        file.pipe(fs.createWriteStream('images/'+sessionID+'/image.jpeg'));
    });


    //CLEANUP
    fs.rmdir('images/'+sessionID, { recursive: true }, (err) => {
        if (err) return err;
    });
}

Advertisement

Answer

I would use promise-based versions of functions that do these operations and then use async/await with those promises:

const stream = require('stream');
const {promisify} = require('util');
const fs = require('fs');
const fsp = fs.promises;
const got = require('got');

const pipeline = promisify(stream.pipeline);

async function run() {
     const sessionID = str.random(50);
     const dir = 'images/'+sessionID;
     await fsp.mkdir(dir);

     await pipeline(
         got.stream('https://en.wikipedia.org/wiki/Main_Page#/media/File:RE_Kaja_Kallas.jpg'),
         fs.createWriteStream(dir + '/image.jpeg')
     );

     // not sure why you're trying to remove a directory that you just 
     // put a file in so it's not empty
     await fsp.rmdir(dir, { recursive: true })
}

run().then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

But, this function isn’t making a lot of sense to me because you’re creating a directory, downloading a file to it and then trying to remove a non-empty directory.

This uses the library got() for downloading the file because it’s my goto library for http requests since it has both stream and promise interfaces.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement