Search code examples
javascriptasync-awaitpromiseform-data

Await a nested function wrapped by a sync func Javascript


The prompt is quite simple but I was not able to figure out a solution, unfortunately.

I have to file a create API then update API. Normally, I can do promise, async/await, or even callback. However, the createAPI is wrapped by a formData function(getLength) since it needs to attach a file. Because of that, I'm not able to await the inner API before firing off an update.

Since getLength does not return anything and it's not a promise, I'm not sure how I may be able to work around this? Thank you!

const createFunc = async () => {
    formData.getLength(async (err, length) => {
        await platformAPI
            .createAPI(formData, length)
            .then((res) => {
                if (res !== 201) {
                    console.log("something went wrong")
                }
                console.log("it works") 
            });
    });
}


const apiFunc = () => {
    createFunc().then(() => updateApi())
}

Solution

  • You can promisify formData.getLength. Either use Node's util.promisify to get the promisified version of getLength, or else promisify it yourself, like this:

    // Promisify getLength:
    const promiseLength = formData =>
        new Promise((resolve, reject) =>
            formData.getLength((err, length) => err ? reject(err) : resolve(length))
        );
    
    const createFunc = () =>
        promiseLength(formData).then(length =>
            platformAPI
            .createAPI(formData, length)
            .then(res => {
                if (res !== 201) console.log("something went wrong")
                else console.log("it works"); // Only print this in the else-case
                return res; // Better return the value
            });
        );
    

    Note that async is not of much use when the only statement in that function is an await. In that case just return the awaited expression and drop the async keyword. And your second use of async does not even have an await... so that is useless.