在我的项目中,我需要通过自定义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/

10-13 01:54