使用msal.js异步获取查询信息的JavaScript Promise问题求助
MSAL.js异步请求顺序执行与结果获取问题
我正在学习使用msal.js,在通过查询异步获取信息时遇到了困境:使用链式then调用时,第一个console.log块会立即执行并打印默认值,只有100毫秒后的延迟块才能拿到正确值。需求是按顺序执行Function01、VerificacionMe、VerificacionMe这三个函数,将结果存入数组后,最后打印数组的完整信息。
源码
const Test009 = async function () { tok = null; arr = ["aa", "bb", "cc"]; try { getTokenPopup(loginRequest) .then((response) => { tok = response.accessToken; t = Function01(response.accessToken).then(function teste(val) { console.log("the val 1 is:" + val + " "); arr[0] = val; }); }) .then((response) => { t = VerificacionMe(tok, tok).then(function teste(val) { console.log("the val 2 is:" + val + " "); arr[1] = val; }); }) .then((response) => { t = VerificacionMe(tok, tok).then(function teste(val) { console.log("the val 3 is:" + val + " "); arr[2] = val; }); }) .then(function teste3(val) { console.log(arr); console.log(arr[0]); console.log(arr[1]); console.log(arr[2]); setTimeout(function () { console.log(arr); console.log(arr[0]); console.log(arr[1]); console.log(arr[2]); }, 100); }); } catch (error) { console.error(`Error: ${error}`); } }; async function Function01(token) { const res = await fetch("https://graph.microsoft.com/v1.0/me/department", { method: "GET", headers: { Authorization: token, "Content-Type": "application/json", }, }); const data = await res.json(); return data.value; } async function VerificacionMe(array, token) { const respuesta = await fetch("https://graph.microsoft.com/v1.0/me/", { method: "GET", headers: { Authorization: token, "Content-Type": "application/json", }, }); const data = await respuesta.json(); return data; }
当前输出
aa bb cc the val 2 is:[object Object] the val 1 is : "Departament" the val 3 is:[object Object] ---------------------------- [object object] is @odata.context : "https://graph.microsoft.com/v1.0/$metadata#users/$entity" businessPhones : ['+52 (55) 5555-5555'] displayName : "Name LastName" givenName : "Name" id : "1111111-2222-3333-4444-555555555555" jobTitle : "Job" mail : "help@help.me" mobilePhone : null officeLocation : "Hell" preferredLanguage : null surname : "LastName" userPrincipalName : "help@help.me"
解决方案
问题核心是你的then链没有正确等待异步操作完成:每个then里的异步调用(Function01、VerificacionMe)没有返回Promise,导致下一个then会直接执行,不会等待前面的异步请求结束。
修改后的代码
既然Test009已经声明为async函数,直接用await替代then链会更清晰,也更容易保证顺序:
const Test009 = async function () { let tok = null; const arr = ["aa", "bb", "cc"]; try { // 先获取token const tokenResponse = await getTokenPopup(loginRequest); tok = tokenResponse.accessToken; // 按顺序执行三个异步函数,等待每个完成后再进行下一个 arr[0] = await Function01(tok); console.log("the val 1 is:" + arr[0] + " "); arr[1] = await VerificacionMe(arr, tok); console.log("the val 2 is:" + arr[1] + " "); arr[2] = await VerificacionMe(arr, tok); console.log("the val 3 is:" + arr[2] + " "); // 此时三个异步操作都已完成,直接打印数组 console.log(arr); console.log(arr[0]); console.log(arr[1]); console.log(arr[2]); } catch (error) { console.error(`Error: ${error}`); } }; async function Function01(token) { const res = await fetch("https://graph.microsoft.com/v1.0/me/department", { method: "GET", headers: { Authorization: `Bearer ${token}`, // 补全Authorization头的规范格式 "Content-Type": "application/json", }, }); const data = await res.json(); return data.value; } async function VerificacionMe(array, token) { const respuesta = await fetch("https://graph.microsoft.com/v1.0/me/", { method: "GET", headers: { Authorization: `Bearer ${token}`, // 补全Authorization头的规范格式 "Content-Type": "application/json", }, }); const data = await respuesta.json(); return data; }
关键修改点
- 用
await替代then链:async/await语法让异步代码逻辑更直观,确保每个异步操作完成后再执行下一个,从根源解决顺序问题。 - 补全Authorization头格式:规范的
Authorization头需要携带Bearer前缀,避免请求因身份验证失败报错。 - 添加变量声明关键字:给
tok和arr加上let/const,避免产生全局变量,符合代码规范。 - 如果坚持用
then链:每个then回调必须返回内部的异步Promise,让下一个then等待其完成,示例如下:getTokenPopup(loginRequest) .then((response) => { tok = response.accessToken; // 返回Function01的Promise,让下一个then等待它完成 return Function01(response.accessToken).then(val => { console.log("the val 1 is:" + val + " "); arr[0] = val; }); }) .then(() => { // 返回VerificacionMe的Promise return VerificacionMe(tok, tok).then(val => { console.log("the val 2 is:" + val + " "); arr[1] = val; }); }) .then(() => { // 返回VerificacionMe的Promise return VerificacionMe(tok, tok).then(val => { console.log("the val 3 is:" + val + " "); arr[2] = val; }); }) .then(() => { // 此时所有异步操作都已完成 console.log(arr); console.log(arr[0]); console.log(arr[1]); console.log(arr[2]); });
修改后即可保证三个异步函数按顺序执行,完成后直接打印数组的完整数据,无需依赖setTimeout。
内容的提问来源于stack exchange,提问作者noEsUnaPrueba NoSeñor
相关产品推荐
相关产品推荐

