在纯javascript中链接承诺

chaining promises in plain javascript

本文关键字:承诺 链接 javascript 在纯      更新时间:2023-09-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)
    })
}

要更清楚,要添加class的元素有

-webkit-transition:15s ease all;

所以我想,使它,原始内容应该淡出,然后ajax内容应该添加到网站。这就是为什么我用承诺。我认为承诺链等待。then()方法完成,然后执行下一个。then()方法。但是ajax内容是在原始内容消失之前添加到站点的,所以它在first .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")
    })
}

每个then回调都是按顺序调用的,promise将在前一个回调中返回一个新的promise时等待。你的代码的问题是,承诺不等待css动画。因为它没有等待,所以它会转到下一个回调,并立即删除你的元素。

你可以在第一个then中创建(并返回)一个新的承诺,对于这个承诺,使用transitionend事件监听器来解析/拒绝这个新承诺。这将使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>