我正在尝试编写运行异步功能的代码,完成后将运行另一段代码。
我曾尝试将async函数置于一个promise中(如下面的代码所示),并且使用then
方法没有成功。
该函数内部发生的情况并不重要,但无论如何我都将其包括在内,以防万一我误会了。
getData = async(file) =>{
let data = await fetch(file);
data = await data.text();
return(data);
}
getDataAndUsername = async() => {
this.setState({data: JSON.parse(await this.getData("/getData"))});
this.setState({username: await this.getData("/user")});
console.log('done');
}
getDataAndUsername是我尝试在其他功能之前运行的异步功能。
CheckInDataBase = (username) => {
console.log('checking In DataBase');
this.state.data.forEach((element)=>{
if(element.username === username){
this.setState({exist: true});
}
});
if (!(this.state.exist)){
axios.post('/createUser', {"username": username, "status": "Working"});
this.setState({exist: true});
}
}
这是我试图在异步运行后运行的常规功能
这是代码:
new Promise((res) => {
this.getDataAndUsername();
res();
}).then(
this.CheckInDataBase(this.state.username)
)
现在发生的是,this.CheckInDatabase在getDataAndUsername完成之前运行。
答案 0 :(得分:2)
您的async
被定义为getDataAndUsername
,已经是一个Promise,无需将其包装在new Promise()
中。您可以这样做:
this.getDataAndUsername().then( _ => {
this.CheckInDataBase(this.state.username);
})
它应该可以工作。
您正在通过以下方式创建新的承诺:
new Promise((res) => {
this.getDataAndUsername();
res();
}) ...
在那里,您正在呼叫this.getDataAndUsername()
,但忽略了它能否解析。该代码将立即调用res
,因此checkInDatabase
在getDataAndUsername
解析之前就已被调用。
您不高兴,请等待getDataAndUsername
解决:
new Promise((res) => {
return this.getDataAndUsername().then(_ => {res()})
}) ...
重点是等待使用then
解决承诺,并添加return
。
但是,如上所述,由于getDataAndUsername
已经是一个承诺,所以不需要这样做。
答案 1 :(得分:0)
正如我在评论中所写,您经常更新状态。这是一个异步过程,因此您可能会通过检查或遍历旧状态来结束。
我建议您尽量减少使用this.setState
并在尽可能多的函数中返回值。这样,您就可以拆分功能,而不依赖于react的状态。
这是我对您的问题的建议:
class App extends React.PureComponent {
getData = async (file) =>{
let data = await fetch(file);
return await data.text();
};
getDataAndUsername = async () => ({
data: JSON.parse(await this.getData("/getData")),
username: JSON.parse(await this.getData("/user"))
});
checkInDataBase = ({ username, data }) => {
console.log('checking In DataBase');
return !!data.find(element => element.username === username);
};
addUser = async username => await axios.post('/createUser', {"username": username, "status": "Working"});
myCheckFunction = async () => {
const dataAndUsername = await this.getDataAndUsername();
if (dataAndUsername) {
if (!this.checkInDataBase(dataAndUsername)) {
const newUser = await this.addUser(dataAndUsername.username);
dataAndUsername.data.push(newUser);
}
// A single place where you update the state
this.setState({
...dataAndUsername,
exists: true
})
}
}
}
答案 2 :(得分:-1)
尝试:
this.getDataAndUsername().then((response) => {
/**
* Your code that you want to run after getDataAndUsername
*/
}, (error) => {
/**
* Handle error here
*/
});
或使用async/await
:
(async function() {
try {
const dataAndUsername = await this.getDataAndUsername();
/**
* Your code that you want to run after getDataAndUsername
*/
} catch(e) {
/**
* Handle error here
*/
}
})();