POST完成后如何从MySQL获取数据

时间:2020-07-02 07:42:40

标签: mysql reactjs express async-await

当用户单击按钮时,我希望应用程序

  • 从输入字段中读取文本
  • 将其发布到MySQL以添加为新行
  • 从MySQL中拉出所有行(包括新行)
  • 使用刚刚提取的新数据更新react组件状态
  • 并为用户重新呈现所有这些数据的列表

我看到的问题是,除非我包括手动延迟(通过setTimeout),否则下拉所有行不包括刚刚发布的行。

这是我的2个函数的样子

// gets all data, updates state, thus triggering react to rerender
  listWords() {
    setTimeout(() => fetch("http://localhost:9000/listWords")
      .then(res => res.text())
      .then(res => this.setState({ wordList: JSON.parse(res)})), 2000)
  }


// sends new word to the MySQL database, then kicks off the listWords process to refetch all data
addWord() {
    fetch("http://localhost:9000/addWord", {
      method: 'POST',
      headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        word: this.state.newWord
      })
    })
    .then(res => res.json())
    .then(this.listWords())
      
  }

我不必在那里有setTimeout,但是当我删除它时,listWords更新中没有新发布的行。

我最好的猜测是

  1. 我正在弄乱承诺.then()的范式,或者
  2. MySQL响应我的POST请求,但实际上直到GET完成才添加行,因此在新行中丢失了。

如何在再次拉出行之前确保POST已成功完成?

我正在使用react,express,sequelize,对于DB,它是docker容器中的MySQL。

1 个答案:

答案 0 :(得分:1)

您确实犯了一个错误,这是我本人也几次陷入的常见陷阱:)

调用addWord()时它将评估then(this.listWords())。这将立即调用listWords()

例如,您将函数传递给then(...)(而不是调用函数),例如:

.then(() => this.listWords())

甚至是这样:

.then(this.listWords)

现在,不是将listWords()的结果传递给then(),而是传递了一个将listWords()调用到then()的函数,因此仅在以下情况下执行listWords()承诺达到了then()


使此行为更加清晰的示例:

在调用函数function foo(arg1) {}时,JS在调用arg1之前需要知道foo的值。让我们采用以下代码:

foo(bar())

在这种情况下,必须在bar()之前调用foo(...),因为arg1将是bar()的返回值。与以下情况相反:

foo(() => bar())

现在,arg1将是一个函数,而不是返回的值bar()。这等效于:

var arg = () => bar();
foo(arg);

与之相反:

var arg = bar();
foo(arg);

很明显会发生什么。

在诸如foo(arg1).bar(arg2).baz(arg3)之类的链接函数中,将在调用foo(...)之前对所有arg求值。


一些帮助调试此类问题的帮助:在浏览器中使用网络检查器。它将显示已执行请求的顺序,在本示例中,您将看到GET请求实际上是在POST请求之前执行的。这可能无法解释为什么会发生,但是您可以更快地理解问题。

相关问题