javascript - 在纯 JavaScript 中链接 promise

标签 javascript ajax promise

我学习 promise ,所以我制作了一个通过 ajax 生成内容的简单网站。

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

我已经制作了调用 promise 并返回内容的脚本

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 内容添加到站点。这就是为什么我使用 promise 。我认为 promise 链接等待 .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会等待。您的代码的问题是 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>

关于javascript - 在纯 JavaScript 中链接 promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32952761/

相关文章:

javascript - 如何捕捉谷歌浏览器审计灯塔

javascript - 从 QML ListView 委托(delegate)调用 JavaScript 对象方法

javascript - (CSRF token 丢失或不正确。)在 Django 中使用 AJAX

reactjs - react hooks setState完成后如何解决promise?

javascript - Promise:链式超时

javascript - 是否可以覆盖已经声明的 Promise 链?

javascript - 发送不带 html 标签的文本

javascript - d3 v4 缩放事件未针对鼠标滚轮/触摸屏触发

php - 使用ajax将数据多次插入表中

javascript - 使用 fetch 而不是 jQuery 的 ajax 进行 GET API 调用