在我的项目中,我需要通过自定义API在db(POST请求)中注册用户。
该操作完成后,我想发出GET请求以获取所有用户,并将新创建的信息(例如id和其他信息)传递到下一个状态(我正在使用Phaser框架开发游戏)。
我想做的是在post请求中使用回调,然后调用另一个可再次检索所有玩家的函数,但它当然不起作用,因为它们是异步操作(尽管我认为我可以通过以下方式解决它:回调)。
这些是我的2个功能:
saveNewUser: function(name, password){
var self = this;
if(name && password){
// create new calibration data for the current user
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://project.herokuapp.com/api/users",true);
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
var input = JSON.stringify({
"name": name,
"password": password,
});
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == 4 && xhttp.status == 200) {
console.log(xhttp.responseText);
self.retrieveNewUser(name);
}
};
xhttp.send(input);
} else {
self.errorMessage.visible = true;
// make text become not visible again after few seconds
self.time.events.add(Phaser.Timer.SECOND * 3, function () {
self.errorMessage.visible = false;
}, this);
}
}
而里面调用的函数:
retrieveNewUser: function (name) {
var self = this;
// save user details in the global variables, get user after registration in db
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://duchennegame.herokuapp.com/api/users', true);
xhr.onload = function () {
var users = JSON.parse(xhr.responseText);
if (xhr.readyState == 4 && xhr.status == "200") {
var userFound = false;
users.forEach(function(user){
if(user.name === name){
// save user details in the global variables
self.game.global.currentUser = user;
self.state.start('welcome');
userFound = true;
}
});
// if user has not been found / wrong password, display error message
if(!userFound){
self.errorMessage.setText('Problem in retrieving the current user');
self.errorMessage.visible = true;
// make text become not visible again after few seconds
self.time.events.add(Phaser.Timer.SECOND * 3, function () {
self.errorMessage.visible = false;
}, self);
}
} else {
console.error(users);
}
};
xhr.send(null);
}
如何确保仅在POST完成后才执行GET请求?
编辑
我意识到此代码永远不会执行,因此即使控制台消息也不会打印:
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
console.log(xhttp.responseText);
self.retrieveNewUser(name);
}
};
但是,它们在this page中提供了以这种方式编写的示例。我有什么想念的吗?
最佳答案
题。为了执行“ xhttp.send(input);”,是否需要调用retrieveNewUser? ?
如果没有,我建议您将saveNewUser函数包装在Promise中。从本质上讲,Promise是回调的一种更高级的形式,它使您可以使异步代码更同步地执行。
因此,您的saveNewUser函数将如下所示:
saveNewUser: function(name, password){
var self = this;
//Returns Promise Object
return new Promise(function(resolve, reject) {
if(name && password){
// create new calibration data for the current user
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://project.herokuapp.com/api/users",true);
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
var input = JSON.stringify({
"name": name,
"password": password,
});
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == 4 && xhttp.status == 200) {
console.log(xhttp.responseText);
//This line of code essentially acts as a return statement
resolve(name);
}
};
xhttp.send(input);
} else {
self.errorMessage.visible = true;
// make text become not visible again after few seconds
self.time.events.add(Phaser.Timer.SECOND * 3, function () {
self.errorMessage.visible = false;
}, this);
}
})};
从那里,您可以通过链接promises并运行以下语句,以同步方式运行这两个功能:
saveNewUser(name, password)
.then(function(name){
retrieveNewUser(name);
});
then函数将回调作为参数。回调接收已解析的数据(在本例中为name),并对其执行某些操作(在本例中,调用retrieveNewUser)。
这样可确保在saveNewUser完成之前,retrieveNewUser()不会运行。
关于javascript - POST请求完成后的GET请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51050289/