【问题标题】:chaining promises in plain javascript用纯 JavaScript 链接 Promise
【发布时间】:2015-10-07 06:50:26
【问题描述】:

我正在学习承诺,所以我创建了一个通过 ajax 生成内容的简单网站。

当用户点击链接时,它会改变网站的内容,但首先它应该淡出原始内容。

我已经编写了调用承诺并返回内容的脚本

function getcontent(url){
return new Promise(function(resolve,reject){

     var xhttp = new XMLHttpRequest();
      xhttp.open("GET", url, true);
      xhttp.onload=function(){
        if(xhttp.status==200){
            resolve(xhttp.response)
        }
        else{
            reject(Error(xhttp.responseText))
        }
      }
      xhttp.send();
    })
    }

以及应该添加内容的函数

function change(url){
    var doc=document.getElementsByClassName("info")[0];
    return getcontent(url).then(function(x){

        doc.children[0].classList.add("remove");
        return x
    }).then(function(x){
        doc.removeChild(doc.children[doc.children.length-1]);
        var div=document.createElement("div");
        div.innerHTML=x;
        doc.appendChild(div)
    })
}

更清楚一点,要添加类的元素有

-webkit-transition:15s ease all;

所以我想,让原始内容淡出,然后将 ajax 内容添加到网站。这就是我使用承诺的原因。我认为承诺链接等待 .then() 方法完成,然后执行下一个 .then() 方法。但是在原始内容消失之前将 ajax 内容添加到站点,因此在第一个 .then() 方法完成之前调用它。我错过了什么?

我尝试在两个单独的函数中使用 ontransitionend 事件作为评论建议,但它不起作用

function getcontent(url){
return new Promise(function(resolve,reject){
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", url, true);
  xhttp.onload=function(){
    if(xhttp.status==200){
        resolve(xhttp.response)
    }
    else{
        reject(Error(xhttp.responseText))
    }
  }
  xhttp.send();
})
}

function change(url){
    var doc=document.getElementsByClassName("info")[0];
     getcontent(url).then(function(x){
     return new Promise(function(res,rej){
    doc.addEventListener("transitionend",function(){
      res(x);
    })});
    doc.children[0].classList.add("remove")

    })
}

【问题讨论】:

    标签: javascript ajax promise


    【解决方案1】:

    每个 then 回调按顺序调用,当前一个回调中返回新的 Promise 时,Promise 将等待。您的代码的问题是承诺不等待 css 动画。由于它不等待,它会转到下一个回调并立即删除您的元素。

    您可以在第一个 then 中创建(并返回)一个新的 Promise,并为该 Promise 使用 transitionend event listener 来解决/拒绝该新 Promise。这将使 promise 等到转换完成,然后执行下一个回调

    var prom = new Promise(function(res,rej){
      var xhttp = new XMLHttpRequest();
      xhttp.open("GET", "https://cors-test.appspot.com/test", true);
      xhttp.onload=function(){
        console.log("loaded");
        if(xhttp.status==200){
          res(xhttp.response)
        }
        else{
          rej(Error(xhttp.responseText))
        }
      }
      xhttp.send();
    });
    
    prom.then(function(data){
      var old = document.querySelector("#content");    
      
      return new Promise(function(res,rej){
        old.addEventListener("transitionend",function(){
          res(data);
        });
        old.classList.add("remove");
      });
    }).then(function(data){
      var parent = document.querySelector("#parent");
      var old = document.querySelector("#content");
      old.remove();
      var div=document.createElement("div");
      div.innerHTML="Data retrieved, length: "+data.length;
      parent.appendChild(div);
    });
    .remove {
      opacity:0;
    }
    
    #parent div {
      -o-transition:all 2s;
      -moz-transition:all 2s;
      -webkit-transition:all 2s;
      transition:all 2s;
    }
    <div id="parent"><div id="content">Content</div></div>

    【讨论】:

    • 我试图在两个单独的函数中实现它但它不起作用我用我现在厌倦的代码更新了我的问题
    • @trolkura,因为您删除了错误部分中的类,所以将 .add('remove') 调用放在 addEventListener 调用之后,就像在我的代码示例中一样
    猜你喜欢
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多