Javascript:Promise()。然后才行

时间:2016-09-24 22:17:09

标签: javascript

我正在尝试为我的网站制作一个加载器动画样式。加载动画是16条,按顺序增加和减少。例如,第一个柱将增加然后减小回原始大小。然后下一个栏将重复此过程,直到所有栏完成,然后停止该过程并显示页面。在这种情况下,因为JavaScript在调用函数时是异步的,所以我使用了一个承诺绕过它。承诺的使用是在前一个完成动画之后为该动画设置动画。目前,我的代码仅动画第一个栏并停在那里。它不会继续为其余部分制作动画。以下是我的所有代码:

重要! 它在javascript上的问题。不要花时间在HTML或CSS上。

var index = -1;

function loading(){
	var loader = document.getElementById("loader");
	display = window.getComputedStyle(loader).display;
	if (display == "block"){
		var child = document.getElementById("loader-ul").getElementsByTagName("div");
		index = index + 1;
		alert("dd");
		animate(child);
	}
}

function animate(element){
	var el = element[index];
	var MaxHeight = false;
	var finished = false;
	function anim(){
		return new Promise(function(resolve, reject){
			if (finished == false){
				if (MaxHeight == false){
					var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
					var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
					height = height + 1;
					Bot = Bot + 0.5;
					el.style.bottom = Bot + "px";
					el.style.height = height + "px";
					if (height <= 100){
						window.requestAnimationFrame(anim);
					}
					else{
						MaxHeight = true;
					}
				}
				if (MaxHeight == true){
					var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
					var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
					height = height - 1;
					Bot = Bot - 0.5;
					el.style.bottom = Bot + "px";
					el.style.height = height + "px";
					if (height >= 50){
						window.requestAnimationFrame(anim);
					}
					else{
						MaxHeight = true;
						finished = true;
						el.style.bottom = 0 + "px";
						el.style.height = 50 + "px";
					}
				}
			}
			else{
				resolve();
			}
		});
	}
	anim().then(loading);
}
body{
	margin: 0px;
	padding: 0px;
	margin: auto;
}

#loader{
	display: block;
	position: fixed;
	height: 100%;
	width: 100%;
	background-color: white;
	z-index: 9999;
}

#loader .center{
	position: relative;
	height: 50px;
	width: 200px;
	background-color: red;
	top: 50%;
	transform: translateY(-50%);
	margin: auto;
}

#loader .center div{
	width: 2px;
	height: 50px;
	background-color: blue;
	float: left;
	padding: 0px;
	margin-right: 5px;
	margin-bottom: 25px;
	position: relative;
}
<body onload="loading()">
    <div id="loader">
			<div class="center" id="loader-ul">
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
				<div></div>
			</div>
		</div>
	</body>

我还有一个指向jsfiddle的链接:

https://jsfiddle.net/6227jjen/

谢谢大家!

注意: 我为调试目的添加了一些警报。

2 个答案:

答案 0 :(得分:1)

问题在于并非所有路径都能解决问题。更大的问题是你的代码创造了许多承诺而不是一个承诺。以下是变化的概要。

function anim () {
  return new Promise (function (resolve) {
    function _anim () {
      if (!finished) {
          _logic();
          // By putting requestAnimationFrame at the end, you can ensure 
          // that it will be called after your logic
          // (assuming finished eventually equals true).
          window.requestAnimationFrame(_anim);
      }
     else 
       resolve();
    }
  });

这是实际修复。

&#13;
&#13;
var index = -1;

function loading() {
  var loader = document.getElementById("loader");
  display = window.getComputedStyle(loader).display;
  if (display == "block") {
    var child = document.getElementById("loader-ul").getElementsByTagName("div");
    index = index + 1;
    alert("dd");
    animate(child);
  }
}

function animate(element) {
  var el = element[index];
  var MaxHeight = false;
  var finished = false;

  function anim() {
    return new Promise(function(resolve, reject) {
      function _anim() {
        if (finished == false) {
          if (MaxHeight == false) {
            var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
            var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
            height = height + 1;
            Bot = Bot + 0.5;
            el.style.bottom = Bot + "px";
            el.style.height = height + "px";
            if (height > 100) {
              MaxHeight = true;
            }
          }
          if (MaxHeight == true) {
            var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
            var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
            height = height - 1;
            Bot = Bot - 0.5;
            el.style.bottom = Bot + "px";
            el.style.height = height + "px";
            if (height < 50) {
              MaxHeight = true;
              finished = true;
              el.style.bottom = 0 + "px";
              el.style.height = 50 + "px";
            }
          }
          window.requestAnimationFrame(_anim);
        } else {
          resolve();
        }
      }
      _anim();
    });
  }
  anim().then(loading);
}
&#13;
body {
  margin: 0px;
  padding: 0px;
  margin: auto;
}
#loader {
  display: block;
  position: fixed;
  height: 100%;
  width: 100%;
  background-color: white;
  z-index: 9999;
}
#loader .center {
  position: relative;
  height: 50px;
  width: 200px;
  background-color: red;
  top: 50%;
  transform: translateY(-50%);
  margin: auto;
}
#loader .center div {
  width: 2px;
  height: 50px;
  background-color: blue;
  float: left;
  padding: 0px;
  margin-right: 5px;
  margin-bottom: 25px;
  position: relative;
}
&#13;
<body onload="loading()">
  <div id="loader">
    <div class="center" id="loader-ul">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

致电window.requestAnimationFrame(anim);永远不会解决您的承诺。它将调用anim,这将创建另一个承诺,如果你已经完成,可能会得到解决,但最初的承诺永远不会实现。

不应该将anim的整个主体包裹在new Promise构造函数中,而应该仅对requestAnimationFrame进行委托,然后使用它来构建承诺链。

function animate(element){
    var el = element[index];
    var MaxHeight = false;
    var finished = false;
    function getFrame() {
        return new Promise(function(resolve) {
            window.requestAnimationFrame(resolve);
        });
    }
    function anim(){
        if (finished == false){
            if (MaxHeight == false){
                var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
                var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
                height = height + 1;
                Bot = Bot + 0.5;
                el.style.bottom = Bot + "px";
                el.style.height = height + "px";
                if (height <= 100){
                    return getFrame().then(anim);
//                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                } else{
                    MaxHeight = true;
                }
            }
            if (MaxHeight == true){
                var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
                var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
                height = height - 1;
                Bot = Bot - 0.5;
                el.style.bottom = Bot + "px";
                el.style.height = height + "px";
                if (height >= 50){
                    return getFrame().then(anim);
//                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                } else{
                    MaxHeight = true;
                    finished = true;
                    el.style.bottom = 0 + "px";
                    el.style.height = 50 + "px";
                }
            }
        }
        return Promise.resolve();
    }
    return anim().then(loading);
}