Async not awaiting the function to complete before executing next line

Issue

I’m using node-mssql. The line return res.send(result) is executed before var result = await client(3), this should not be the case because I have await on var result = await client(3).

After debugging I came to a point where the following code is not waiting for the function to finish.

request.bulk(table, (err, result) => {
    if(err){
        return err
    }
    if(result){
        return result
    }
})

Here’s the rest of the sample code.

app.get('/', async (req, res) => {
    var result = await client(3)
    return res.send(result)
})

const client = async (client_id) => {
    ...
    const table = new sql.Table('table_name')
    table.create = true
    table.columns.add('a', sql.Int, {nullable: true, primary: true})
    table.columns.add('b', sql.VarChar(50), {nullable: false})
    table.rows.add(777, 'test')

    const request = new sql.Request()
    request.bulk(table, (err, result) => {
        if(err){
            return err
        }
        if(result){
            return result
        }
    })
    ...
}

Solution

request.bulk() is not using promises so it’s not connected at all to what client() returns. You can fix that by manually promisifying it:

const client = async (client_id) => {
    ...
    const table = new sql.Table('table_name')
    table.create = true
    table.columns.add('a', sql.Int, {nullable: true, primary: true})
    table.columns.add('b', sql.VarChar(50), {nullable: false})
    table.rows.add(777, 'test')

    const request = new sql.Request()
    const result = await new Promise((resolve, reject) => {
        request.bulk(table, (err, result) => {
            if(err){
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
    ...
    return result;
}

And, keep in mind that await only does something useful when you await a promise that resolves only when you have completed the work. But, your client() function returns a promise by virtue of being async and that promise isn’t connected at all to when request.bulk() finishes. So, to fix that, the code above created a promise that is tied to when request.bulk() finishes and uses await with it. That causes the promise that parent async function returns to then be tied to when the actual work is done.

FYI, if your database driver has native promise support built-in, then you can use that directly without having to promisify it yourself.

Answered By – jfriend00

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published