因此,我目前正在尝试使用他们的Noops Challenge为Github的Fizzbot API创建一个简单的测验应用。
我正在将当前问题和下一个问题的URL存储并组装到全局变量中。
var baseurl = "https://api.noopschallenge.com";
var nextQuestion = "/fizzbot/questions/1";
var url = "";
我有一个提交功能,可以将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>
答案 0 :(得分:0)
全局变量存储在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.nextQuestion
和this.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
在另一个作用域内设置全局值。
答案 1 :(得分:0)
似乎它与实际变量范围的关系比与代码的异步方面的关系更多。与其处理一堆凌乱的this
引用,我只是将我的大多数全局变量放在一个对象中,该对象无论如何最终变得更加有意义。
使用带有getter和setter的对象,我可以访问整个代码中的所有变量。