当用户单击按钮时,我希望应用程序
我看到的问题是,除非我包括手动延迟(通过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更新中没有新发布的行。
我最好的猜测是
.then()
的范式,或者如何在再次拉出行之前确保POST已成功完成?
我正在使用react,express,sequelize,对于DB,它是docker容器中的MySQL。
答案 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
请求之前执行的。这可能无法解释为什么会发生,但是您可以更快地理解问题。