使用JavaScript调用Graph API遇await语法错误及Promise Pending问题求助
解决Graph API调用中的await语法错误与Promise未决问题
问题描述
- 使用
await时触发语法错误:
SyntaxError: await is only valid in async functions and the top level bodies of modules at internalCompileFunction (node:internal/vm:73:18) at wrapSafe (node:internal/modules/cjs/loader:1176:20) at Module._compile (node:internal/modules/cjs/loader:1218:27) at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) at Module.load (node:internal/modules/cjs/loader:1117:32) at Module._load (node:internal/modules/cjs/loader:958:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:23:47
原代码:
const { Client } = require("@microsoft/microsoft-graph-client"); const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials"); const { ClientSecretCredential } = require("@azure/identity"); const credential = new ClientSecretCredential(tenantId, clientId, clientSecret); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ["https://graph.microsoft.com/.default"] }); const client = Client.initWithMiddleware({ debugLogging: true, authProvider // Use the authProvider object to create the class. }); let user = await client.api('/users/72b2bde1-9b18-4451-8aa0-f61da82426c2') .select('displayName') .get(); console.log(user);
- 移除
await后出现Promise未决:
PS C:\TenantVerse> node .\ConnectGraph.js Promise { <pending> }
解决方案
方法一:将代码包裹在async函数中执行
Node.js默认的CommonJS模块不支持顶层await,需把Graph API调用逻辑放到async函数内执行:
const { Client } = require("@microsoft/microsoft-graph-client"); const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials"); const { ClientSecretCredential } = require("@azure/identity"); async function getUser() { const credential = new ClientSecretCredential(tenantId, clientId, clientSecret); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ["https://graph.microsoft.com/.default"] }); const client = Client.initWithMiddleware({ debugLogging: true, authProvider }); let user = await client.api('/users/72b2bde1-9b18-4451-8aa0-f61da82426c2') .select('displayName') .get(); console.log(user); } // 执行async函数并捕获异常 getUser().catch(err => console.error('调用失败:', err));
方法二:改用ES模块支持顶层await
若想直接使用顶层await,可通过两种方式切换为ES模块:
- 将文件后缀改为
.mjs - 在项目根目录的
package.json中添加"type": "module"
修改后的代码(无需包裹函数):
import { Client } from "@microsoft/microsoft-graph-client"; import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials"; import { ClientSecretCredential } from "@azure/identity"; const credential = new ClientSecretCredential(tenantId, clientId, clientSecret); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ["https://graph.microsoft.com/.default"] }); const client = Client.initWithMiddleware({ debugLogging: true, authProvider }); let user = await client.api('/users/72b2bde1-9b18-4451-8aa0-f61da82426c2') .select('displayName') .get(); console.log(user);
方法三:使用Promise的then/catch处理(兼容旧环境)
不想用async/await的话,可通过then方法处理Promise结果:
const { Client } = require("@microsoft/microsoft-graph-client"); const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials"); const { ClientSecretCredential } = require("@azure/identity"); const credential = new ClientSecretCredential(tenantId, clientId, clientSecret); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ["https://graph.microsoft.com/.default"] }); const client = Client.initWithMiddleware({ debugLogging: true, authProvider }); client.api('/users/72b2bde1-9b18-4451-8aa0-f61da82426c2') .select('displayName') .get() .then(user => console.log(user)) .catch(err => console.error('调用失败:', err));
关键说明
- 错误本质:CommonJS模块不支持顶层
await,await仅能在async函数内部使用;移除await后,client.api().get()返回的是未决议的Promise对象,直接打印会显示<pending>。 - 推荐优先使用方法一或方法二,
async/await写法更清晰易读。
内容的提问来源于stack exchange,提问作者CompileErr
相关产品推荐
相关产品推荐

