Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export async function from a node module

I'm trying to write a node module, to handle my various db calls. I want to use async/await where ever I can, but I'm having some issues with it.

I've been using promises a bit, and export those functions fine. Example:

function GetUsernames() {
    return new Promise(function (resolve, reject) {
        sql.connect(config).then(function () {
            new sql.Request()
                .query("SELECT [UserName] FROM [Users] ORDER BY [LastLogin] ASC").then(function (recordset) {
                    resolve(recordset);
                }).catch(function (err) {
                    reject(err);
                });
        });
    });
}

And then I export in the following:

module.exports = {
    GetUsernames: GetUsernames,
    GetScopes: GetScopes,
    UpdateToken: UpdateToken,
    SetOwner: SetOwner
};

But, how should I do this, with an async function, to use the async/await that is available in node7?

Do I still just return a promise? I tried doing that, but when I then call it in my code, it doesn't work.

const db = require("dataprovider");
...
var result = await db.GetUsernames();

It gives me:

SyntaxError: Unexpected identifier

on the db name (works fine if I just use the promise functions, with then().)

Maybe my google skills are terrible, but I haven't managed to google anything I could use, on this issue.

How on earth do I make an async function, in my module, that I can await elsewhere?

like image 391
Nicolai Avatar asked Apr 02 '17 12:04

Nicolai


2 Answers

To turn on the await keyword, you need to have it inside an async function.

const db = require("dataprovider");
...
let result = getUserNames();

async function getUserNames() {
    return await db.GetUsernames();
}

See http://javascriptrambling.blogspot.com/2017/04/to-promised-land-with-asyncawait-and.html for more information.

Also, just as an FYI, it a code convention to start function with lowercase, unless you are returning a class from it.

like image 52
Kevin Williams Avatar answered Sep 20 '22 22:09

Kevin Williams


async - await pattern really makes your code easier to read. But node do not allow for global awaits. You can only await an asynchronous flow. What you trying to do is to await outside async flow. This is not permitted. This is kind of anti-pattern for node application. When dealing with promises, what we actually do is generate an asynchronous flow in our program. Our program continue without waiting for promise. So you can export your functions as async but cannot await for them outside async flow. for example.

const db = require('dataprovider');
...
let result = (async () => await db.GetUserNames())();
console.log(result); // outputs: Promise { <pending> }

Thus, async-await pattern works for async flow. Thus use them inside async functions, so that node can execute them asynchronously. Also, you can await for Promises as well. for example.

let fn = async () => await new Promise( (resolve, reject)=>{...} );
fn().then(...);

Here you have created async function 'fn'. This function is thenable. also you can await for 'fn' inside another async function.

let anotherFn = async () => await fn();
anotherFn().then(...);

Here we are waiting for async function inside a async function. Async-Await pattern makes your code readable and concise. This is reflected in large projects.

like image 25
Market Queue Avatar answered Sep 18 '22 22:09

Market Queue