[在下面的函数中,我有这两个变量,size
和total
,在整个功能块中应该是必需的,但是当执行到达第三个if
时,它们将显示值undefined
:
function update_cart() {
var cart_size = document.getElementById('cart_size');
var cart_status = document.getElementById('cart_status');
var cart_total = document.getElementById('cart_total');
var size, total;
if(cart_size !== null) {
var cliente = cart_size.dataset.cliente;
var url = cart_size.dataset.url;
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
size = xhr.responseText;
cart_size.innerHTML = size;
if(size == 0)
cart_size.style.display = 'none';
else
cart_size.style.display = 'block';
}
};
var formData = new FormData();
formData.append("cliente", cliente);
xhr.send(formData);
}
if(cart_total !== null) {
var cliente = cart_total.dataset.cliente;
var url = cart_total.dataset.url;
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
total = xhr.responseText;
var currency = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(total);
cart_total.innerHTML = currency;
}
};
var formData = new FormData();
formData.append("cliente", cliente);
xhr.send(formData);
}
if(cart_status !== null) {
switch(size) {
case 0:
cart_status.innerHTML = 'A cesta de compras está vazia.';
document.getElementById('table').style.display = 'none';
break;
case 1:
cart_status.innerHTML = size + ' produto adicionado na cesta, com valor ' + total;
document.getElementById('table').style.display = 'block';
break;
default:
cart_status.innerHTML = size + ' produtos adicionados na cesta, com valor ' + total;
document.getElementById('table').style.display = 'block';
break;
}
}
}
我已经尝试用var
和let
声明它们,结果相同。在cart_status
存在的页面中,cart_size
和cart_total
都存在。
任何人都可以提供有关如何解决该问题的提示?
您必须了解,对xhr.onreadystatechange
的呼叫是异步呼叫。因此,如果您试图在发生/解决异步操作之前捕获/使用size
或total
的值,您将在其中获得undefined
值。
您需要做的是在它们来自异步调用之后,使用回调来处理它们的值。
这不起作用,因为这些变量是在回调中定义的。
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
size = xhr.responseText;
cart_size.innerHTML = size;
if(size == 0)
cart_size.style.display = 'none';
else
cart_size.style.display = 'block';
}
};
此代码被异步调用,请在稍后收到网络调用的响应时阅读:如果要访问变量,则必须将使用该变量的代码移到回调中。
[正如其他人所说,XMLHttpRequest
默认是异步的。这意味着它不会阻止脚本的其余部分执行。
所以您可以在第一个请求完成后发出第二个请求:
var firstRequest = new XMLHttpRequest();
firstRequest.open('POST', 'someUrl');
firstRequest.onreadystatechange = function() {
if (firstRequest.readyState == 4 && firstRequest.status == 200) {
size = firstRequest.responseText;
var secondRequest = new XMLHttpRequest();
secondRequest.open('POST', 'someOtherUrl');
secondRequest.onreadystatechange = function() {
if (secondRequest.readyState == 4 && secondRequest.status == 200) {
total = secondRequest.responseText;
// Now you should have both size and total variables available
}
};
}
};
不漂亮,但是应该可以。