You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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;
}

关键修改点

  1. 用await替代then链:async/await语法让异步代码逻辑更直观,确保每个异步操作完成后再执行下一个,从根源解决顺序问题。
  2. 补全Authorization头格式:规范的Authorization头需要携带Bearer前缀,避免请求因身份验证失败报错。
  3. 添加变量声明关键字:给tok和arr加上let/const,避免产生全局变量,符合代码规范。
  4. 如果坚持用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:03:23