 <p>Each then callback is called in order, and the promise will wait when a new promise is returned in the previous callback. The problem with your code is that promises do not wait for css animations. And since it does not wait it goes to the next callback and removes your element right away.</p> <p>You can create(and return) a new promise in the first <code>then</code>, and for that promise use a <a href="https://developer.mozilla.org/en-US/docs/Web/Events/transitionend" rel="nofollow">transitionend event listener</a> to resolve/reject that new promise. This will make the promise wait till the transition is done and then execute the next callback</p> <p><div class="snippet" data-lang="js" data-hide="false"> <div class="snippet-code"> <pre class="snippet-code-js lang-js prettyprint-override"><code>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); });</code></pre> <pre class="snippet-code-css lang-css prettyprint-override"><code>.remove { opacity:0; } #parent div { -o-transition:all 2s; -moz-transition:all 2s; -webkit-transition:all 2s; transition:all 2s; }</code></pre> <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="parent"&gt;&lt;div id="content"&gt;Content&lt;/div&gt;&lt;/div&gt;</code></pre> </div> </div> </p>