web-dev-qa-db-ja.com

NodeJSで非同期関数を必要とする

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;

このファイルはTwitter.jsとしてlibフォルダに保存されます

私の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できませんか?

8
Jon Hunter

あなたのコードはすでに正しいです。 何も変更せずに in Twitter.jsそれを使用する2つのオプションがあります:

  1. asyncでマークされた関数は、常にpromiseを返します。したがって、次のことを簡単に行うことができます。

    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に加えて単なるシンタックスシュガーです。

11
slebetman

あなたは正しい方向に進んでいますが、awaitinside非同期関数でしか使用できません。したがって、構造が逆になり、いくつかの変更を加えることで簡単に解決できます。ただし、コードを見落とし、構造を変更することをお勧めします。しかし、これがあなたのコードの動作バージョンです:

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);
  }
})()

これは、コードが逆方向になっていることを示すためのコードの簡単な修正であり、いくつかの構造上の変更が必要です。

4
Sven