变量在其范围内未持有值

问题描述 投票:0回答:3

[在下面的函数中,我有这两个变量,sizetotal,在整个功能块中应该是必需的,但是当执行到达第三个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;
    }
  }
}

我已经尝试用varlet声明它们,结果相同。在cart_status存在的页面中,cart_sizecart_total都存在。

任何人都可以提供有关如何解决该问题的提示?

javascript scope var let
3个回答
0
投票

您必须了解,对xhr.onreadystatechange的呼叫是异步呼叫。因此,如果您试图在发生/解决异步操作之前捕获/使用sizetotal的值,您将在其中获得undefined值。

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


0
投票

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

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

此代码被异步调用,请在稍后收到网络调用的响应时阅读:如果要访问变量,则必须将使用该变量的代码移到回调中。


0
投票

[正如其他人所说,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
      }
    };
  }
};

不漂亮,但是应该可以。

© www.soinside.com 2019 - 2024. All rights reserved.