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

Posted

技术标签:

【中文标题】POST完成后如何从MySQL获取数据【英文标题】:How to fetch data from MySQL after POST completes 【发布时间】:2020-10-22 18:15:07 【问题描述】:

当用户点击按钮时,我希望应用能够

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

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

这就是我的两个函数的样子

// 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 更新没有新发布的行。

我最好的猜测是

    我搞砸了 promise .then() 范式,或者 MySQL 响应我的 POST 请求,但直到 GET 完成后才真正添加行,因此错过了新行。

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

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

【问题讨论】:

听起来像是情况 2。您是否登录了端口 9000 请求处理程序?从日志中检查(执行 2 个相应 SQL 的顺序),然​​后您可以验证它是否是案例 2。 【参考方案1】:

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

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

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

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

甚至像这样:

.then(this.listWords)

现在,不是将listWords() 的结果传递给then(),而是传递一个函数,该函数将调用listWords()then(),因此只有在Promise 到达then() 时才执行listWords()


让这种行为更加清晰的示例:

调用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 请求之前执行的。这可能无法解释为什么会发生,但您可以更快地理解问题。

【讨论】:

非常有帮助,但由于一个新问题仍然无法正常工作。网络选项卡是一个很好的提醒,GET 发生在发布前。所以我将 arg 设为一个函数,但现在它永远不会被调用。我试着把它放在.then(() => this.listWords()).finally(() => this.listWords()) 中,以防它遇到错误。但是这两种方法都不会调用该函数(通过控制台日志和观察网络选项卡显示)。有任何想法吗?我对 promises 不熟悉,所以我感到困惑并不奇怪。 好吧,我知道我做错了什么,但我不明白。我在调用fetch(...) 时点击了后端API,但在实际的快速路由中,我没有res.send(...)。为什么在后端快速路由中缺少 res.send(...) 会导致 promise 无法解析(因此不会在前端调用 .then(...) @mgs 我建议在你的承诺链末尾添加一个.catch(e => console.log(e))。通过这种方式,您可以了解为什么它可能已停止处理。如果您看到任何事情发生,则链可能正在某处等待返回,在这种情况下,我建议将日志记录添加到链的每个步骤以查看问题 在这种情况下也要检查浏览器控制台。 Promise 中未处理的异常通常会记录在那里 @mgs 也许是一个猜测:如果您从不发回响应,则该请求可能只是处于待处理状态。这意味着它应该在一段时间后超时,然后抛出错误。根据请求类型和浏览器,这可能需要很长时间。您将能够在 Network Inspector 中看到这一点。将列出一个仍待处理的请求。

以上是关于POST完成后如何从MySQL获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MySQL 数据库中获取数据并在 javascript 自动完成中使用?

GET / POST方法无法使用json从mysql数据库获取数据到html

vue导航完成前后获取数据

asp问题,如何获取post后获得的数据

从 Mysql 数据库获取数据到 Android

获取 url 时如何强制网络浏览器使用 POST?