【问题标题】:JavaScript using async/await to make sure I retrieve value before implementation, but still get 'undefined' returnedJavaScript 使用 async/await 确保我在实现之前检索值,但仍然返回“未定义”
【发布时间】:2021-11-19 07:51:16
【问题描述】:

代码

async function getStudents() {
  var reqObj = new RequestHandler("/students/all/");
  let { students } = await reqObj.sendRequest();
  console.log(students, students.length);
  return students;
}

export default function Students(props) {
  var students = getStudents();
  return (
    <main className="content-section">
      <h1>Students</h1>
      <span className="help-text">
        You have {`${students.length}`} students.
      </span>
    </main>
  );
}

...

export class RequestHandler {
  // Base class for handling requests
  constructor(url, method = "GET", contentType = "application/json") {
    this.url = url;
    this.method = method;
    this.contentType = contentType;
    this.request_conf = {
      method: this.method,
      url: this.url,
      headers: {
        "Content-Type": this.contentType,
        "X-CSRFToken": cookies.get("csrftoken"),
      },
      credentials: "same-origin",
    };
  }
  async sendRequest() {
    const response = await axios(this.request_conf);
    var data = isResponseOK(response);
    return data;
  }
}

getStudents() 函数中的console.log(students, students.length); 给了我预期的输出:[] 0,但尽管尝试使其成为一个异步函数等等,Students 组件仍然得到undefined 作为值背部。 在Students 组件中读取相同值的最简单方法是什么?

免责声明

我是 JavaScript 的初学者,尤其是 Promises,所以如果我在这里遗漏了一些非常简单和/或明显的东西,请告诉我,不要对它有害 :)

【问题讨论】:

  • 您也忘记了在呼叫者中等待您的学生,但这不是您唯一的问题,正如 Drew 指出的那样。那个render方法应该是每秒能调用百次,所以不能阻塞
  • @oligofren - 你能指出你的意思吗?我的 n00b 太大了,不能马上得到它……:
  • Ariart 的答案(现已隐藏)和 draw 都添加了 await 构造以供参考,从 cmets 看来您已经很好理解了????
  • 关于阻塞的事情:react 期望所有的渲染方法几乎立即执行并返回结果。因此任何这样的方法都不能花时间等待网络结果。实际调用和任何等待都需要在方法“外部”进行处理,因此需要 useEffect 和 useState

标签: javascript reactjs async-await


【解决方案1】:

React 的“渲染”函数是一个同步的纯函数。它不能等待值被呈现。这就是生命周期方法和状态的用途。

使用useState 钩子将students 数组保持在状态,并使用带有空依赖数组的useEffect 钩子来调用getStudents 并等待Promise 解决和排队状态更新和触发重新渲染。

export default function Students(props) {
  // state to hold values
  const [students, setStudents] = React.state([]);

  // effect to fetch values
  React.useEffect(() => {
    getStudents().then(students => setStudents(students));
  }, []); // <-- empty dependency == run once on component mount

  return (
    <main className="content-section">
      <h1>Students</h1>
      <span className="help-text">
        You have {`${students.length}`} students.
      </span>
    </main>
  );
}

文档

如果您更喜欢 async/await 而不是 Promise 链:

React.useEffect(() => {
  const fetchStudents = async () => {
    try {
      const students = await getStudents();
      setStudents(students);
    } catch(error) {
      // handle error, log it, etc...
    }
  };
  fetchStudents();
}, []);

【讨论】:

  • 在你写的async/await版本的代码中,我不是要写const students = await getStudents();吗?
  • @W1ck3d 啊,是的,完全。抱歉,??‍♂️ 这是一个复制/粘贴错误,我以某种方式放弃了await 的通话。感谢您的关注。 ?
猜你喜欢
  • 2019-04-22
  • 2020-10-02
  • 2020-04-06
  • 2021-10-21
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
相关资源
最近更新 更多