【问题标题】:React – Async / Await doesn’t seem to be waitingReact – Async / Await 似乎没有在等待
【发布时间】:2019-01-17 06:35:05
【问题描述】:

我之前在“无法读取未定义的属性'数据'”的错误消息下发布了这个问题。但是在深入研究了几个小时的过程中,我发现我的问题真的归结为我的“异步/等待”似乎不是。 . . .等待!是的,我确实检查了这里已经提出的这个问题的其他几个版本。 :)

我正在构建一个 React 表单,该表单将包含几个下拉框,其中填充来自 MongoDB 的数据。我是 React 的新手,也是 MongoDB 的初学者。

我只需将所有代码塞入一个文件即可成功地将数据放入下拉列表中。现在,我正在尝试通过将部分正确拆分为单独的文件来开始重构代码。这就是我遇到这个“数据延迟”问题的地方。

当“componentDidMount”调用“fetchProjects”函数时,该函数会使用“项目服务”文件中的“getProjects”函数从 MongoDB 中获取项目列表。当“fetchProjects”中的 console.log 运行时,它会以未定义的形式返回。但是在数据集返回未定义(并且过程出错)之后,我确实从“getProjects”函数中获得了项目对象数组的控制台日志。

我已经能够使这个过程在“getProjects”函数中使用硬编码的对象数组数据,这告诉我问题在于从 MongoDB 实际获取数据所需的时间量。

请告诉我有一种方法可以在不使用 Redux 的情况下解决这个问题! :D

这是我的 App.js 文件 -

import React, { Component } from "react";
import "./App.css";
import { getProjects } from "./services/svcProjects";

class App extends Component {
  state = {
    data: {
      selProject: ""
    },
    projects: []
  };

  async componentDidMount() {
    await this.fetchProjects();
  }

  async fetchProjects() {
    const { data: projects } = await getProjects();
    console.log(projects);
    this.setState({ projects });
  }

  render() {
    return (
      <div className="App">
        <h1>Project Log</h1>
        <label htmlFor={"selProject"}>{"Project"}</label>
        <select name={"selProject"} id={"selProject"} className="form-control">
          <option value="" />
          {this.state.projects.map(a => (
            <option key={a._id} value={a.project}>
              {a.project}
            </option>
          ))}
        </select>
      </div>
    );
  }
}

export default App;

这是“项目服务”文件。再次请注意,此处的 console.log 语句表明我仍在从 MongoDB 获取数据。该数据返回 App.js 文件的时间太长了。

另外,顺便说一句,我意识到在这个文件中包含我的 Mongo 连接信息是一个巨大的安全漏洞。我稍后会解决这个问题。

import {
  Stitch,
  RemoteMongoClient,
  AnonymousCredential
} from "mongodb-stitch-browser-sdk";

export function getProjects() {
  const client = Stitch.initializeDefaultAppClient("------");
  const db = client
    .getServiceClient(RemoteMongoClient.factory, "-----")
    .db("----------");
  client.auth
    .loginWithCredential(new AnonymousCredential())
    .then(() =>
      db
        .collection("--------")
        .find({}, { sort: { Project: 1 } })
        .asArray()
    )
    .then(res => {
      console.log("Found docs", res);
      console.log("[MongoDB Stitch] Connected to Stitch");
      return res;
    })
    .catch(err => {
      console.error(err);
    });
}

【问题讨论】:

  • 你可以尝试从你的 API 调用中返回一个 Promise 并处理它,而不是 async-await 吗?
  • 你在fetchProject函数中看到console.log(projects)的结果了吗?
  • Satyaki,感谢您抽出宝贵时间提出建议!实际上,tbuglc 下面的解决方案详细阐述了同样的想法。非常感谢您抽出宝贵时间为解决方案做出贡献!
  • sdkcy,感谢您提出这个问题!我在 fetchProjects() 中的 console.log 中得到“未定义”,但我在 getProjects() 中看到 console.log 中的数据,这有助于我确定这两点之间发生了故障。

标签: reactjs react-async


【解决方案1】:

我认为在您的 getProjects() 服务中添加退货将解决您的问题。

import {
  Stitch,
  RemoteMongoClient,
  AnonymousCredential
} from "mongodb-stitch-browser-sdk";

export function getProjects() { //add async if you need to await in func body
  const client = Stitch.initializeDefaultAppClient("------");
  const db = client
    .getServiceClient(RemoteMongoClient.factory, "-----")
    .db("----------"); // if these above are async, then await them as well.

    // added return keyword here
    return client.auth // should return Promise to await in your component
    .loginWithCredential(new AnonymousCredential())
    .then(() =>
      db
        .collection("--------")
        .find({}, { sort: { Project: 1 } })
        .asArray()
    )
    .then(res => {
      console.log("Found docs", res);
      console.log("[MongoDB Stitch] Connected to Stitch");
      return res;
    })
    .catch(err => {
      console.error(err);
    });
}

编辑 1:

对于重构,我认为结合 redux 和 redux-saga 会给你很好的关注点分离,如果你打算这样做的话,可以很容易地编写测试。 但总的来说,我认为上面的这个调整至少可以解决你的问题。

【讨论】:

  • 检查这个codesandbox我创建来模拟你的问题
  • Ch-ching!!做到了!只需在顶部添加“返回”即可解决问题。非常感谢,tbuglc!我肯定会考虑你的 redux 建议。现在,我很高兴知道我的前进道路要简单得多。再次感谢您抽出宝贵时间提供帮助!
  • @JoelMorgan 很高兴听到这个消息:-)
猜你喜欢
  • 2018-02-21
  • 2019-06-03
  • 1970-01-01
  • 2018-05-25
  • 2018-09-28
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多