簡體   English   中英

在 Node v14.14.0 中使用頂級 await 功能時,“SyntaxError:await 僅在異步函數中有效”

[英]'SyntaxError: await is only valid in async function' when using top level await feature in Node v14.14.0

我正在嘗試使用 Node v14.8 中添加的新頂級 await。 請參閱此處此處了解更多信息。 我沒有在這里找到有關使用此新功能的問題的問題,但我希望這不是重復的。 最接近的是@DanStarns 對這個問題的回答,但我也嘗試過他的解決方案(他的回答是在 14.8 版本之前)。

  • 我知道 IIFE 過去一直是首選的解決方法之一,但這個問題與新的頂級等待功能有關,以及為什么盡管已隨 Node 14.8 發布但仍會引發錯誤

我正在將我的 Axios 實例從我的控制器中提取到一個獨立的服務中。 在該服務文件中,我嘗試實例化然后導出使用 Spotify API 中存儲的授權標頭創建的 Axios 實例。 由於然后將其導入我的控制器(傳遞到構造函數然后它導出new SpotifyApiController(SpotifyApiService) )並且導入是同步的,我試圖使用新的頂級 await 功能在啟動/導入時完全實例化它,但得到以下錯誤:

[nodemon] starting `babel-node bin/www.js --harmony-top-level-await --experimental-repl-await`
E:\projects\harmonic-mixing-companion\server\services\SpotifyApiService.mjs:117
var SpotifyApiService = await createApiService();
                        ^^^^^

SyntaxError: await is only valid in async function
    at wrapSafe (internal/modules/cjs/loader.js:979:16)
    at Module._compile (internal/modules/cjs/loader.js:1027:27)
    at Module._compile (E:\projects\harmonic-mixing-companion\server\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .mjs] (E:\projects\harmonic-mixing-companion\server\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (E:\projects\harmonic-mixing-companion\server\controllers\/SpotifyApiController.js:1:1)

從錯誤來看,看起來 babel-node 正在正確地轉換我的代碼,因為const SpotifyApiService = ...變成了var SpotifyApiService = ... 我還在我的babel.config.json添加了"@babel/plugin-syntax-top-level-await"

該服務的文件擴展名為.mjs 我也嘗試在我的服務器的 package.json 中設置"type": "module" ,但這也沒有結果。 如果我錯了,請糾正我,但將我的整個后端服務器設置為模塊對我來說也不合適,因為對我來說它聽起來不像是一個模塊化單元(相對於可重用的SpotifyApiService )。

使用console.log(process.version);雙重檢查我的節點版本console.log(process.version); 在我的主條目文件的頂部,它打印了預期的 14.14.0 版本。


SpotifyApiController.js片段:

import SpotifyApiService from '../services/SpotifyApiService.mjs';
import handleHttpError from '../handlers/handleHttpError';

class SpotifyApiController {
  constructor(spotifyApiService) {
    this.spotifyApi = spotifyApiService;
  }
  ...
}

SpotifyApiService.mjs片段:

...
const createApiService = async () => {
  const accessToken = await authorizeApp();

  console.log(accessToken);

  const authHeader = { Authorization: `Bearer ${accessToken}` };

  const axiosInstance = axios.create({
    baseURL: 'https://api.spotify.com/v1',
    headers: authHeader,
  });

  createAuthRefreshInterceptor(axiosInstance, authorizeApp);

  return axiosInstance;
};

const SpotifyApiService = await createApiService();

export default SpotifyApiService;

package.json依賴項:

  "devDependencies": {
    "@babel/cli": "~7.12.1",
    "@babel/core": "~7.12.1",
    "@babel/eslint-parser": "~7.12.1",
    "@babel/node": "~7.12.1",
    "@babel/plugin-proposal-class-properties": "~7.12.1",
    "@babel/plugin-syntax-top-level-await": "~7.12.1",
    "@babel/plugin-transform-arrow-functions": "~7.12.1",
    "@babel/plugin-transform-runtime": "~7.12.1",
    "@babel/preset-env": "~7.12.1",
    "@babel/preset-react": "~7.12.1",
    "babel-loader": "~8.1.0",
    "nodemon": "~2.0.5"
  },
  "dependencies": {
    "axios": "~0.20.0",
    "axios-auth-refresh": "~3.0.0",
    "cookie-parser": "~1.4.5",
    "cors": "~2.8.5",
    "debug": "~4.2.0",
    "dotenv": "~8.2.0",
    "express": "~4.17.1",
    "querystring": "~0.2.0"
  }

服務器使用以下 npm 腳本啟動: "dev-server": "nodemon --exec babel-node bin/www.js --ignore dist/"

您可以將其包裝在 async 函數中:

var SpotifyApiService = (async()=> await createApiService())();

在你可以使用than 之后,catch

正如文檔所示,babel 只為這個特性啟用“語法”,

僅語法

此插件僅啟用此功能的解析。 Babel 不支持轉換頂級 await ,但您可以使用 Rollup 的 ExperimentalTopLevelAwait 或 webpack@5 的 Experiments.topLevelAwait 選項。

這只是意味着 babel 在編譯你的代碼時不會抱怨,但它實際上並沒有實現會主動轉換一行的步驟,比如var SpotifyApiService = await createApiService(); 進入有效的 ES5。

因此,執行您的代碼(瀏覽器、節點)的任何內容都會抱怨,因為他們不知道如何處理此功能。

問題是頂級 await 僅在 ES 模塊中受支持。 換句話說,您要么必須將"type": "module"到您的 package.json 或將您的.js文件重命名為.mjs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM