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 自动完成中使用?