异步/等待功能并不总是正确运行

问题描述 投票:1回答:2

我正在开发一个react-native / nodeJS项目,并且使用async / await函数对后端进行Axios API调用时遇到问题。

这里是代码:

const TimeTable = () => {
  const [attendedCourses, setAttendedCourses] = useState([]);
  const [courseSchedules, setCourseSchedules] = useState([]);

  useEffect(() => {
    getUserCourses();
    getCourseSchedule();
    console.log(courseSchedules);
  }, []);

  const getCourseSchedule = async () => {
    for (const item of attendedCourses) {
      try {
        const res = await axios.get(`/api/lesson/findById/${item.courseId}`);
        setCourseSchedules((prev) => [
          ...prev,
          {
            id: res.data._id,
            name: res.data.name,
            schedule: [...res.data.schedule],
          },
        ]);
      } catch (err) {
        const error = err.response.data.msg;
        console.log(error);
      }
    }
  };

  const getUserCourses = async () => {
    const userId = "12345678"; //hardcoded for testing purpose
    try {
      const res = await axios.get(`/api/users/lessons/${userId}`);
      setAttendedCourses(res.data);
    } catch (err) {
      const error = err.response.data.msg;
      console.log(error);
    }
  };

  return (...); //not important

};

export default TimeTable;

getUserCourses()方法的行为正确,并且始终返回以attendedCourses状态保存的对象数组。第二种方法getCourseSchedule()无法正常工作。 useEffect()中的console.log()在大多数情况下会打印一个空数组。有人可以向我解释原因吗?谢谢!

javascript async-await axios
2个回答
1
投票

虽然该方法是异步的,但实际的useEffect不会以异步方式处理它,并且直到您到达useEffect中的console.log时才会等待。如果将console.log放入getCourseSchedule方法中,并在等待后记录结果,则每次都会显示正确的结果。

您正在混淆每种方法的异步特性。您的代码不在useEffect中等待,而是在实际方法中等待,而其余useEffect继续执行。

如果您真的想在useEffect中查看结果,请尝试做:

useEffect(() => {
  const apiCalls = async () => {
    await getUserCourses();
    await getCourseSchedule();
    console.log(courseSchedules);
  }

  apiCalls()
})

0
投票

您的useEffect具有一个空数组作为依赖项,这意味着当courseSchedules具有初始值(空数组)时,它仅在初始渲染之前运行一次)>

要在更改时查看courseSchedules,您应该添加另一个useEffect,如下所示:

 useEffect(() => {
    console.log(courseSchedules);
  }, [courseSchedules]);
© www.soinside.com 2019 - 2024. All rights reserved.