【问题标题】:async/await function not always behave correctlyasync/await 函数并不总是表现正确
【发布时间】:2020-09-25 19:13:45
【问题描述】:

我正在开发一个 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() 大部分时间打印一个空数组。 有人可以向我解释为什么吗?谢谢!

【问题讨论】:

  • 因为您在收到服务器的任何响应之前就记录了该值。
  • 试试await getUserCourses()await getCourseSchedule()

标签: javascript async-await axios


【解决方案1】:

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

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

如果你真的想在 useEffect 中看到结果,请尝试这样做:

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

  apiCalls()
})

【讨论】:

  • 我使用 console.log 只是为了测试。我实际上需要在getUserCourses()getCourseSchedule() 完成他们的工作之后执行一个函数。无论如何,我继续在控制台中看到一个空数组。还有其他解决方案吗? @Danyal
【解决方案2】:

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

要查看 courseSchedules 的变化,您应该像这样添加另一个 useEffect

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

【讨论】:

    猜你喜欢
    • 2018-11-06
    • 2019-07-01
    • 1970-01-01
    • 2017-12-17
    • 2019-06-27
    • 2017-09-11
    相关资源
    最近更新 更多