最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Requiring an async function in NodeJS - Stack Overflow

programmeradmin2浏览0评论

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 ?

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 ?

Share Improve this question asked Jul 12, 2017 at 9:37 Jon HunterJon Hunter 8802 gold badges8 silver badges18 bronze badges 5
  • 1 what nodejs version? – Naeem Shaikh Commented Jul 12, 2017 at 9:38
  • 1 8.1.4 (running on Ubuntu) – Jon Hunter Commented Jul 12, 2017 at 9:41
  • 3 the function getAccessToken = async () => shouldnt be async, and the peice of code accessKey = await getAccessToken(); should be inside an async function – Naeem Shaikh Commented Jul 12, 2017 at 9:46
  • 1 if I add console.log(getAccessToken); below const getAccessToken = require('./lib/twitter').getAccessToken; it outputs [AsyncFunction: getAccessToken] which would suggest it is? – Jon Hunter Commented Jul 12, 2017 at 9:46
  • 1 Ok I think I get what you say now. I'll do some investigation, but thanks for your help @Naeem – Jon Hunter Commented Jul 12, 2017 at 9:49
Add a comment  | 

2 Answers 2

Reset to default 18

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.

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.

发布评论

评论列表(0)

  1. 暂无评论