在前端遇到的小问题??

用的vue3 和element plus,在代码中

const find = async () => {
  const res = await axios.put('http://localhost:8080/travel/find/' + id);
  categorys.value = res.data.data;
  console.log(res.data.data);
  const code = res.data.data[0].ydcode;
  localStorage.setItem('code', code);
  // console.log(categorys.value.id)
  // console.log(code.ydcode);
};
find();

console.log(localStorage.getItem('code'));
const code1 = localStorage.getItem('code');
console.log(code1);
const flag = code1 == 1 ? true : false;
console.log(flag);

每次code1获取到的值都是上一次存入的值,网上搜说是因为异步的关系,具体应该怎么修改请大佬指导!

阅读 1.7k
6 个回答
find().then(() => {
    console.log(localStorage.getItem('code')
})

find函数作用域中才是异步等待的 不是当前逻辑都是的异步。
这个函数如果需要改造的话 应该只让函数做一件事。

const find = () => {
  return new Promise(async (resolve) => {
    let res = await axios.put('http://localhost:8080/travel/find/' + id)
    categorys.value = res.data.data;
    resolve(res.data.data[0].ydcode)
  })
}

find().then((code: number) => {
  //  其他逻辑都不应该在 find 函数内部做
  const flag = code === 1;
  console.log(flag)
})

let flag = (code1 == 1) ? true : false;
直接简写 const flag = code1 === 1;

问题分析

const find = async () => {
  const res = await axios.put('http://localhost:8080/travel/find/' + id);
  categorys.value = res.data.data;
  console.log(res.data.data);
  const code = res.data.data[0].ydcode;
  localStorage.setItem('code', code);
  // console.log(categorys.value.id)
  // console.log(code.ydcode);
};
find();

console.log(localStorage.getItem('code'));
const code1 = localStorage.getItem('code');
console.log(code1);
const flag = code1 == 1 ? true : false;
console.log(flag);

问题出现在异步操作上,这里的 localStorage.setItem('code', code); 写在一个异步函数中,是一个异步操作,而在下面的代码中,你立即尝试获取 localStorage.getItem('code') 的值。由于异步操作的特性,存储操作尚未完成,所以你得到的值可能是上一次的值。

为了解决这个问题,你可以将后续的代码逻辑放在 localStorage.setItem 的回调函数中,确保在存储操作完成后再执行后续操作。

解决

const find = async () => {
  try {
    const res = await axios.put('http://localhost:8080/travel/find/' + id);
    categorys.value = res.data.data;
    console.log(res.data.data);

    const code = res.data.data[0].ydcode;
    
    // 使用Promise确保localStorage.setItem操作完成后再执行后续代码
    return new Promise((resolve) => {
      localStorage.setItem('code', code);
      resolve();
    });
  } catch (error) {
    console.error("Error in find:", error);
  }
};

find().then(() => {
  // 在localStorage.setItem完成后执行后续代码
  console.log(localStorage.getItem('code'));
  const code1 = localStorage.getItem('code');
  console.log(code1);
  const flag = code1 == 1 ? true : false;
  console.log(flag);
});

建议

题主对于js的事件循环机制还不够熟悉,建议题主多回顾JS基础内容。

这里主要涉及的知识点:【Promise】、【async/await】、【事件循环机制】

对于js执行引擎,在执行find()后,并没有等find()执行完成。而是立即继续执行下面的console.log的代码(宏任务),而find中的代码(微任务)会被放在主代码执行完后才会执行。


const getCode = async (id) => {
  const res = await axios.put('http://localhost:8080/travel/find/' + id);
  return res.data.data[0].ydcode;
};

const init = async () => {
  const code = await getCode('xxxx');
  localStorage.setItem('code', code);
};

const main = async () => {
  await init();

  const code = localStorage.getItem('code');
  // do whatever you want
};

main();

这段代码可能存在以下问题:
1、可能抛出错误,但未处理
2、categorys.value可能不是数组
3、code可能不是对象
4、尝试访问code的属性时可能会出错
5、尝试访问code1时可能会出错

const res = await axios.put('http://localhost:8080/travel/find/' + id);

try {
 const data = res.data.data;
 if (data && data.length > 0) {
   categorys.value = data;
   console.log(data);
   const code = data[0];
   localStorage.setItem('code', JSON.stringify(code));
   console.log(localStorage.getItem('code'));
   const code1 = JSON.parse(localStorage.getItem('code'));
   console.log(code1);
   const flag = code1.ydcode === '1';
   console.log(flag);
 } else {
   console.log('No data found');
 }
} catch (error) {
 console.error('Error:', error);
}

这段代码假设categorys.value是一个数组,code是一个对象,code1是一个字符串,并且localStorage.getItem('code')返回一个有效的JSON字符串。

给你批注了一下:

const find = async () => {
    const res = await axios.put('http://localhost:8080/travel/find/' + id);
    //todo 建议加上条件判断,可能取不到值
    categorys.value = res.data.data;
    console.log(res.data.data);
    const code = res.data.data[0].ydcode;
    // 其实是没必要走localStorage ,如果只是临时存数据,
    // 这里可以直接续后面的逻辑
    localStorage.setItem('code', code);
    //看起来你似乎最后是为了flag ,完全可以改代码,最后返回布尔值
    // console.log(categorys.value.id)
    // console.log(code.ydcode);
};
// 建议学习一下 promise
// await 写法更简洁
await find();

console.log(localStorage.getItem('code'));
const code1 = localStorage.getItem('code');
console.log(code1);
const flag = code1 == 1 ? true : false;
console.log(flag);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题