首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Javascript函数中执行承诺?

如何在Javascript函数中执行承诺?
EN

Stack Overflow用户
提问于 2019-11-29 20:41:36
回答 2查看 55关注 0票数 2

如果我有一个有3个承诺的函数,它们应该一个接一个地运行,在另一个函数中,它们出现在函数的代码中?我有一个代码,在第三个也是最后一个承诺中,我应该可以访问变量sizetotal,在其他两个承诺中分配了变量,但是它们仍然是undefined。我是不是漏掉了这个承诺的概念?我最近才开始了解他们。

我的代码:

代码语言:javascript
运行
复制
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;

  var promise1 = new Promise(function(resolve, reject) {
    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) {
          resolve(xhr.responseText);
        }
      };
      var formData = new FormData();
      formData.append("cliente", cliente);
      xhr.send(formData);
    } else {
      reject();
    }
  });

  promise1.then(function(value) {
    size = value;
    cart_size.innerHTML = size;
    if(size == 0)
      cart_size.style.display = 'none';
    else
      cart_size.style.display = 'block';
  }).catch(function(){
    console.log('erro1');
  });

  var promise2 = new Promise(function(resolve, reject) {
    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) {
          resolve(xhr.responseText);
        }
      };
      var formData = new FormData();
      formData.append("cliente", cliente);
      xhr.send(formData);
    } else {
      reject();
    }
  });

  promise2.then(function(value) {
    total = value;
    var currency = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(total);
    cart_total.innerHTML = currency;
  }).catch(function(){
    console.log('erro2');
  });

  var promise3 = new Promise(function(resolve, reject) {
    if(cart_status !== null) {
      resolve();
    } else {
      reject();
    }
  });

  promise3.then(function() {
    console.log('promise3');
    console.log('size: '+size+', total: '+total);
    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;
    }
  }).catch(function(){
    console.log('erro3');
  });
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-29 20:47:24

允诺执行不会阻止调用函数。因此,您的所有3项承诺都会立即执行,从而在sizetotal变量中生成total值。试试这个:

代码语言:javascript
运行
复制
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;

  var promise1 = new Promise(function(resolve, reject) {
    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) {
          resolve(xhr.responseText);
        }
      };
      var formData = new FormData();
      formData.append("cliente", cliente);
      xhr.send(formData);
    } else {
      reject();
    }
  });

  var promise2 = new Promise(function(resolve, reject) {
    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) {
          resolve(xhr.responseText);
        }
      };
      var formData = new FormData();
      formData.append("cliente", cliente);
      xhr.send(formData);
    } else {
      reject();
    }
  });

  var promise3 = new Promise(function(resolve, reject) {
    if (cart_status !== null) {
      resolve();
    } else {
      reject();
    }
  });

  promise1
    .then(function(value) {
      size = value;
      cart_size.innerHTML = size;
      if (size == 0) cart_size.style.display = "none";
      else cart_size.style.display = "block";

      promise2
        .then(function(value) {
          total = value;
          var currency = new Intl.NumberFormat("pt-BR", {
            style: "currency",
            currency: "BRL"
          }).format(total);
          cart_total.innerHTML = currency;

          promise3
            .then(function() {
              console.log("promise3");
              console.log("size: " + size + ", total: " + total);
              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;
              }
            })
            .catch(function() {
              console.log("erro3");
            });
        })
        .catch(function() {
          console.log("erro2");
        });
    })
    .catch(function() {
      console.log("erro1");
    });
}

我刚刚移动了下一个承诺的调用--前一个承诺的回调,这样每个承诺都只在上一个承诺完成之后才被执行。如果您需要其他订单,或者需要并行化请求,请阅读更多关于承诺这里的内容。

票数 1
EN

Stack Overflow用户

发布于 2019-11-29 20:53:34

这三个承诺是同时执行的,因为在等待任何承诺完成之前,您都在初始化它们。如果您希望承诺一个接一个地运行,并且能够捕获不同承诺的不同错误,则应该使用异步/等待:

代码语言:javascript
运行
复制
async function update_cart() {
  // ...
  try {
    var value = await promise1;
    size = value;
    // Rest of code inside promise1.then
  } catch(err) {
    console.log('erro1');
  }
}

对promise2和promise3重复这一步骤。函数update_cart现在将返回一个承诺,该承诺将在promise1、promise2和promise3依次解析时解决。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59110763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档