Javascript 变量的值不在其范围内

Javascript 变量的值不在其范围内,javascript,scope,var,let,Javascript,Scope,Var,Let,在下面的函数中,我有两个变量,size和total,这两个变量应该在整个函数块中都是可以访问的,但是当执行到达第三个if时,它们表示值未定义的: function update_cart() { var cart_size = document.getElementById('cart_size'); var cart_status = document.getElementById('cart_status'); var cart_total = document.getEleme

在下面的函数中,我有两个变量,
size
total
,这两个变量应该在整个函数块中都是可以访问的,但是当执行到达第三个
if
时,它们表示值
未定义的

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\u status
的页面中,同时存在
cart\u size
cart\u total


任何人都可以给出如何解决该问题的提示?

您必须了解对
xhr.onreadystatechange
的调用是一个异步调用。因此,如果您试图在异步操作发生/解决之前捕获/使用
size
total
的值,您将在其中获得
未定义的值


您需要做的是在它们来自异步调用之后,使用回调来处理它们的值。

这不起作用,因为这些变量是在回调中定义的

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';
      }
    };
此代码被异步调用,读取:稍后,当您收到网络呼叫的响应时。
如果要访问该变量,必须将使用该变量的代码移动到回调中

正如其他人所说,默认情况下是异步的。这意味着它不会阻止脚本的其余部分执行

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 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
      }
    };
  }
};

虽然不漂亮,但它应该可以工作。

这两个变量是什么?购物车大小和购物车总数?我不明白?你的意思是什么?来吧,只指定你正在谈论的两个变量是什么。你似乎没有在代码中我能看到的任何地方给它们赋值。我认为你的第三个
if()
是在你的请求完成之前执行的。