首页 > 解决方案 > POST完成后如何从MySQL获取数据

问题描述

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

我看到的问题是拉下所有行不包括刚刚发布的行,除非我包括手动延迟(通过 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,对于数据库,它是 docker 容器中的 MySQL。

标签: mysqlreactjsexpressasync-await

解决方案


你确实犯了一个错误,一个我自己也陷入过几次的常见陷阱:)

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

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

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

甚至像这样:

.then(this.listWords)

现在,不是将结果传递listWords()then()它,而是传递一个将调用的函数,listWords()因此只有在 Promise 达到 this 时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(...)


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


推荐阅读