繁体   English   中英

在POST请求中修改全局变量

[英]Modifying global variables inside of POST request

因此,我目前正在尝试使用Fizzbot API为Github的Noops Challenge制作一个简单的测验应用程序。

我正在全局变量中存储和组装当前问题和下一个问题的URL。

var baseurl = "https://api.noopschallenge.com";
var nextQuestion = "/fizzbot/questions/1";
var url = "";

我有一个Submit函数,它将POST请求发送到服务器,并在答案正确的情况下接收下一个问题的URL。

function submit() {
    var answer = document.getElementById("answer").value;

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {

            var response = JSON.parse(this.responseText);

        this.nextQuestion = response.nextQuestion; fizzbot
        this.url = baseurl + this.nextQuestion;

        console.log("Next Question: " + this.url);  
        }
    };

    xhttp.open("POST", this.url, true);
    xhttp.setRequestHeader("Content-type", "application/json");
    xhttp.send(answer);

}

除了我的提交按钮,我还有一个下一个按钮。 提交正确答案后,以下功能仍将https://api.noopschallenge.com/fizzbot/questions/1打印到日志中。

function next() {
    console.log(this.url);
}

我很确定它与POST请求的异步性质有关,但是不确定解决它的最佳方法是什么。 我已经发布了一个更完整的代码片段,以说明正在发生的事情。

 var question = ""; var baseurl = "https://api.noopschallenge.com"; var nextQuestion = "/fizzbot/questions/1"; var url = ""; function load() { this.url = this.baseurl + this.nextQuestion var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = JSON.parse(this.responseText); this.question = response.message; document.getElementById("question").innerHTML = this.question; } }; xhttp.open("GET", this.url, true); xhttp.send(); } function submit() { var answer = document.getElementById("answer").value; var responseObject = {answer: answer} var responseJSON = JSON.stringify(responseObject); var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = JSON.parse(this.responseText); this.nextQuestion = response.nextQuestion; this.url = baseurl + this.nextQuestion; document.getElementById("result").innerHTML = response.result; document.getElementById("nextQuestion").innerHTML = response.nextQuestion; console.log("Next Question: " + this.url); } }; xhttp.open("POST", this.url, true); xhttp.setRequestHeader("Content-type", "application/json"); xhttp.send(responseJSON); } function next() { console.log("URL to load: " + this.url); //GET request next question } 
 <!DOCTYPE html> <html> <head> <title>Noops Challenge | FizzBot Bot</title> <script src="Fizzbot.js" type="text/javascript"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="main.css"> </head> <body onload="load()"> <nav class="navbar navbar-dark bg-dark"> <a class="navbar-brand" href="#"> <img src="https://noopschallenge.com/static/animation/fizzbot/images/img_3.png" width="30" height="30" class="d-inline-block align-top" alt=""> FizzBuzz Quiz </a> <!-- <span class="navbar-brand mb-0 h1">FizzBuzz Quiz</span> --> </nav> <div class="container"> <div class="row" style="margin-top:5%;"> <div class="col-sm-2"></div> <div class="col-sm-8"> <div class="card"> <div class="card-header"> Question <span id="questionNumber">1</span> </div> <div class="card-body"> <h5 id="question" class="card-title">Filler Question</h5><br> Answer: <input type="text" id="answer"> <p class="card-text"><br> Result: <span id="result"></span><br> Next Question: <span id="nextQuestion"></span><br> </p> <button class="btn btn-primary" onclick="submit()" value="">Submit</button> <button class="btn btn-primary" onclick="next()" value="">Next</button> </div> </div> </div> <div class="col-sm-2"></div> </div> </div> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html> 

全局变量存储在window对象中。 this可以引用window以及几乎所有其他对象。 另外,不使用this可能也会使您获得全局变量。

这将在全局范围内运行:

function load() {
  this.url = this.baseurl + this.nextQuestion

this === window ,因此this.url是根据全局变量构建的。

上下文在这里更改:

  ...
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var response = JSON.parse(this.responseText);
      this.question = response.message;

      document.getElementById("question").innerHTML = this.question;
    }
  };

在这里, this是指xhttp对象。 设置this.question ,您将在xhttp上创建一个新属性,并使用该值设置<h5 id="question">文本。 这行得通,只是不会更改您的全局question变量。

再次使用全局变量:

  xhttp.open("GET", this.url, true);
  ...
}

使用提交按钮时会发生类似的事情:

function submit() {
  ...
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var response = JSON.parse(this.responseText);

      this.nextQuestion = response.nextQuestion;
      this.url = baseurl + this.nextQuestion;

this.nextQuestionthis.url都在此xhttp对象中创建属性。 但是,由于您没有放this. baseurl前面,并且没有具有该名称的局部变量,将使用全局变量! 因此,您暗中在执行此操作: xhttp.url = window.baseurl + xhttp.nextQuestion

这就是为什么它将显示一个不错的新完整URL:

      console.log("Next Question: " + this.url);
    }
  };

但是同样,请求本身仍然使用初始URL完成,因为我们离开了xhttp范围,并且在这里使用了从未更改的全局值:

  xhttp.open("POST", this.url, true);
  ...
}

... 和这里:

function next() {
  console.log("URL to load: " + this.url);
  //GET request next question
}

长话短说:使用window.url在另一个作用域内设置全局值。

关于MDN上的“ this”

似乎它与实际变量作用域的关系远大于与代码异步方面的关系。 相反,处理一堆凌乱的this引用,我只是把我的大部分全局的,其最终目的让更多的意义反正物体内部。

通过使用带有getter和setter的对象,我可以访问整个代码中的所有变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM