Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Requiring an async function in NodeJS

I am trying to get my head around async/await in NodeJS.

I have a function in a file as follows:

const getAccessToken = async () => {
  return new Promise((resolve, reject) => {

    const oauthOptions = {
      method: 'POST',
      url: oauthUrl,
      headers: {
        'Authorization': 'Basic ' + oauthToken
      },
      form: {
        grant_type: 'client_credentials'
      }
    };

    request(oauthOptions)
      .then((err, httpResponse, body) => {
        if (err) {
          return reject('ERROR : ' + err);
        }
        return resolve(body.access_token);
      })
      .catch((e) => {
        reject('getAccessToken ERROR : ' + e);
      });
  });
};

module.exports = getAccessToken;

This file is saved as twitter.js in a lib folder

In my index.js file I have the following:

const getAccessToken = require('./lib/twitter');

let accessToken;

try {
  accessToken = await getAccessToken();
} catch (e) {
  return console.log(e);
}

console.log(accessToken);

I get an error trying to run this code saying:

>   accessKey = await getAccessToken();
>                     ^^^^^^^^^^^^^^
> 
> SyntaxError: Unexpected identifier
>     at createScript (vm.js:74:10)
>     at Object.runInThisContext (vm.js:116:10)
>     at Module._compile (module.js:533:28)
>     at Object.Module._extensions..js (module.js:580:10)
>     at Module.load (module.js:503:32)
>     at tryModuleLoad (module.js:466:12)
>     at Function.Module._load (module.js:458:3)
>     at Function.Module.runMain (module.js:605:10)
>     at startup (bootstrap_node.js:158:16)
>     at bootstrap_node.js:575:3

Can I not await the required function as it is marked async ?

like image 959
Jon Hunter Avatar asked Jul 12 '17 09:07

Jon Hunter


People also ask

Is NodeJS require async?

In this article, you will learn how you can simplify your callback or Promise based Node. js. js is an asynchronous event-driven JavaScript runtime and is the most effective when building scalable network applications.

Why we use async in NodeJS?

With Node v8, the async/await feature was officially rolled out by the Node to deal with Promises and function chaining. The functions need not to be chained one after another, simply await the function that returns the Promise. But the function async needs to be declared before awaiting a function returning a Promise.

Why we use async instead of promises?

Promise chains can become difficult to understand sometimes. Using Async/Await makes it easier to read and understand the flow of the program as compared to promise chains.

What is async operation in NodeJS?

Asynchronous programming in Node. js. Asynchronous I/O is a form of input/output processing that permits other processing to continue before the transmission has finished.


2 Answers

Your code is already correct. Without changing anything in twitter.js you have two options to use it:

  1. Functions marked with async always return promises. Therefore you can simply do:

    const getAccessToken = require('./lib/twitter');
    
    getAccessToken().then(accessToken => {
        console.log(accessToken);
    })
    
  2. All functions that return promises can be awaited upon but you cannot use await outside of an async marked functions. So you can also do:

    const getAccessToken = require('./lib/twitter');
    
    (async function () {
        var accessToken = await getAccessToken();
        console.log(accessToken);
    })();
    

The async/await keywords does not change how async functions behave. You still cannot wait on async functions synchronously, you can only do that inside an asynchronous function. Async/await is just a syntax sugar on top of promises.

like image 140
slebetman Avatar answered Oct 06 '22 00:10

slebetman


You are on the right track, however await can only be used inside an async function. So you have your structure backwards, and can be easily solved by changing a few things. However I suggest you overlook your code and make some structural changes. But here is a working version of your code:

const getAccessToken = () => {
  return new Promise((resolve, reject) => {

    const oauthOptions = {
      method: 'POST',
      url: oauthUrl,
      headers: {
        'Authorization': 'Basic ' + oauthToken
      },
      form: {
        grant_type: 'client_credentials'
      }
    };

    request(oauthOptions)
      .then((err, httpResponse, body) => {
        if (err) {
          return reject('ERROR : ' + err);
        }
        return resolve(body.access_token);
      })
      .catch((e) => {
        reject('getAccessToken ERROR : ' + e);
      });
  });
};

module.exports = getAccessToken;

And then:

const getAccessToken = require('./lib/twitter');

(async function() {
  try {
    let accessToken = await getAccessToken();
    console.log(accessToken);
  } catch (e) {
    return console.log(e);
  }
})()

This is a simple fix to your code to illustrate that you've got it backwards, and some structural changes are in order.

like image 26
Svenskunganka Avatar answered Oct 05 '22 22:10

Svenskunganka