【问题标题】:Requiring an async function in NodeJS在 NodeJS 中需要一个异步函数
【发布时间】:2017-12-16 15:54:35
【问题描述】:

我正试图了解 NodeJS 中的 async/await。

我在一个文件中有一个函数如下:

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;

此文件在lib 文件夹中另存为twitter.js

在我的index.js 文件中,我有以下内容:

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

let accessToken;

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

console.log(accessToken);

我在尝试运行此代码时遇到错误:

>   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

我不能await 所需的功能,因为它被标记为async 吗?

【问题讨论】:

  • 什么nodejs版本?
  • 8.1.4(在 Ubuntu 上运行)
  • 函数getAccessToken = async () => 不应该是异步的,代码accessKey = await getAccessToken(); 应该在异步函数中
  • 如果我在const getAccessToken = require('./lib/twitter').getAccessToken; 下方添加console.log(getAccessToken);,它会输出[AsyncFunction: getAccessToken],这表明它是什么?
  • 好吧,我想我明白你现在所说的了。我会做一些调查,但感谢您的帮助@Naeem

标签: javascript node.js asynchronous async-await


【解决方案1】:

您的代码已经正确。在twitter.js无需更改任何内容,您有两种选择:

  1. 标有async 的函数总是返回承诺。因此,您可以简单地这样做:

    const getAccessToken = require('./lib/twitter');
    
    getAccessToken().then(accessToken => {
        console.log(accessToken);
    })
    
  2. 所有返回 Promise 的函数都可以在 awaited 上,但你不能在 async 标记的函数之外使用 await。所以你也可以这样做:

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

async/await 关键字不会改变异步函数的行为方式。您仍然不能同步等待异步函数,您只能在异步函数中执行此操作。 Async/await 只是 Promise 之上的语法糖。

【讨论】:

  • 我遇到了同样的问题。我有一个异步函数,在我的索引文件中,它是这样导出的:module.exports = {importedAsync: require('./myAsyncFunction') } 最后,我从 index.js 的另一个地方再次导入它。 const { importAsync } = require('./lib/index.js').结果,我得到:“importedAsync 不是函数”。就我而言,它是通过直接导入 myFunction 来解决的: const myAsyncFunction = require('./lib/myAsyncFunction.js')。效果很好。
【解决方案2】:

您在正确的轨道上,但是 await 只能在内部异步函数中使用。所以你的结构倒退了,可以通过改变一些事情来轻松解决。但是,我建议您忽略您的代码并进行一些结构更改。但这是您的代码的工作版本:

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;

然后:

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

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

这是对您的代码的简单修复,以说明您已将其倒退,并且一些结构更改是按顺序进行的。

【讨论】:

  • 这里不需要使用promise。 async 关键字是一个承诺生成器。
  • 谢谢@Svenskunganka,一切顺利。感谢您的帮助
  • @Sven 我有一个类似的用例。尽管我需要使我的 Token 可以访问我的代码中的所有其他功能。我怎样才能做到这一点?在这种情况下,如果我没记错的话,我只能在访问令牌之后调用其他函数。如果我在这个文件中声明了另一个需要 accessToken 的异步函数,我将不得不一次又一次地调用它。与需要它的功能一样多。有什么想法吗?
猜你喜欢
  • 2017-05-15
  • 2020-02-17
  • 1970-01-01
  • 2017-07-12
  • 2020-03-04
  • 2020-12-31
  • 2019-05-22
  • 2021-07-14
  • 1970-01-01
相关资源
最近更新 更多