JS动画实现回调地狱promise的实例代码详解


Posted in Javascript onNovember 08, 2018

1. js实现动画

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>animate</title>
  <style>
    .ball {
      width: 40px;
      height: 40px;
      margin-bottom: 5px;
      border-radius: 20px;
    }
    .ball1 {
      background: red;
    }
    .ball2 {
      background: blue;
    }
    .ball3 {
      background: yellow;
    }
  </style>
</head>
<body>
  <div class="ball ball1" style="margin-left: 0"></div>
  <div class="ball ball2" style="margin-left: 0"></div>
  <div class="ball ball3" style="margin-left: 0"></div>
  <script>
    var ball1 = document.querySelector(".ball1");
    var ball2 = document.querySelector(".ball2");
    var ball3 = document.querySelector(".ball3");
    function animate(ball, left, callback) {
      setTimeout(function () {
        var marginLeft = parseInt(ball.style.marginLeft, 10);
        if (marginLeft === left) {
          callback && callback();
        } else {
          if (marginLeft < left) {
            marginLeft += 2;
          } else {
            marginLeft -= 2;
          }
          ball.style.marginLeft = marginLeft + "px";
          animate(ball, left, callback);
        }
      }, 13);
    }
    animate(ball1, 100, function () {
      animate(ball2, 200, function () {
        animate(ball3, 300, function () {
          animate(ball1, 200, function () {
            animate(ball3, 200, function () {
              animate(ball2, 180, function () {
                animate(ball2, 220, function () {
                  animate(ball2, 200, function () {
                    console.log("over");
                  })
                })
              })
            })
          })
        }) 
      })
    });
  </script>
</body>
</html>

上述代码就可以实现一个动画。注意下面几点:

•动画的实现往往依赖于setTimeout。
•注意ele.style.marginLeft如果开始能够获取,必须从元素的style中设置了才能获取,否则获取不到。
•利用callback可以实现虽然使用了setTimeout还能串行执行。

但是这产生了回调地狱,代码简单点还好说,一旦代码复杂了,我们将很难处理其中的逻辑。所以这时就可以用到es6中的promise了。

Promise的写法如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>animate</title>
  <style>
    .ball {
      width: 40px;
      height: 40px;
      margin-bottom: 5px;
      border-radius: 20px;
    }
    .ball1 {
      background: red;
    }
    .ball2 {
      background: blue;
    }
    .ball3 {
      background: yellow;
    }
  </style>
</head>
<body>
  <div class="ball ball1" style="margin-left: 0"></div>
  <div class="ball ball2" style="margin-left: 0"></div>
  <div class="ball ball3" style="margin-left: 0"></div>
  <script>
    var ball1 = document.querySelector(".ball1");
    var ball2 = document.querySelector(".ball2");
    var ball3 = document.querySelector(".ball3");
    function promiseAnimate(ball, left) {
      return new Promise(function (resolve, reject) {
        function animate(ball, left) {
          setTimeout(function () {
            var marginLeft = parseInt(ball.style.marginLeft, 10);
            if (marginLeft === left) {
              resolve();
            } else {
              if (marginLeft < left) {
                marginLeft += 2;
              } else {
                marginLeft -= 2;
              }
              ball.style.marginLeft = marginLeft + "px";
              animate(ball, left);
            }
          }, 13);
        }
        animate(ball,left);
      });
    }
    promiseAnimate(ball1, 500)
    .then(function () {
      return promiseAnimate(ball2, 200);
    })
    .then(function () {
      return promiseAnimate(ball3, 300);
    })
    .then(function () {
      return promiseAnimate(ball1, 200);
    })
    .then(function () {
      return promiseAnimate(ball3, 200);
    })
    .then(function () {
      return promiseAnimate(ball2, 180);
    })
    .then(function () {
      return promiseAnimate(ball2, 220);
    })
    .then(function () {
      return promiseAnimate(ball2, 200);
    })
  </script>
</body>
</html>

这同样可以达到效果,并且这样做的好处是,修改更加容易一些。对于promise,有几点需要注意:

1.在执行promise相关函数的时候,要返回一个promise对象,这是常用的做法。
2.只有返回了promise对象,我们才能实用then。
3.并且在then中还要返回promise对象,这样我们就可以不断的使用then()来管理异步。
4.在promise执行之后,要使用resolve()来表明这个promise执行的结束。 这样,才能执行then方法。

问题: 在then中如果直接执行promiseAnimate(ball2, 200);不可以吗?  为什么一定要return呢?

答: 当然不可以,因为如果直接执行,确实返回了一个promise对象,但是这个promise对象只是在then下面的函数中啊, 我们必须在这个函数继续返回这个promise对象才能达到继续使用then的目的。

其中resolve()代表着这个异步过程的结束。

综上所述: 动画多用setTimeout和调用自己的方式执行,当然,使用setInterval也是一样的,只是前者我们更为推荐。 无论是使用setTimeout还是setInterval,都不可避免的会产生如果解决异步的问题。 之前我们解决异步的方式是使用回调函数,但是回调函数非常容易就会产生回调地狱,所以用promise会更好一些。

总结

以上所述是小编给大家介绍的JS动画实现回调地狱promise的实例代码详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery 行背景颜色的交替显示(隔行变色)实现代码
Dec 13 Javascript
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
Apr 24 Javascript
转换字符串为json对象的方法详解
Nov 29 Javascript
form.submit()不能提交表单的原因分析
Oct 23 Javascript
JavaScript事件委托用法分析
Jan 24 Javascript
JS实现浏览器状态栏文字从右向左弹出效果代码
Oct 27 Javascript
深入理解Javascript中的自执行匿名函数
Jun 03 Javascript
jQuery遍历节点树方法分析
Sep 08 Javascript
基于iscroll.js实现下拉刷新和上拉加载效果
Nov 28 Javascript
JavaScript实现QQ列表展开收缩扩展功能
Oct 30 Javascript
Vue2.0 slot分发内容与props验证的方法
Dec 12 Javascript
微信小程序中的店铺评分组件及vue中用svg实现的评分显示组件
Nov 16 Javascript
深入解析ES6中的promise
Nov 08 #Javascript
vue中promise的使用及异步请求数据的方法
Nov 08 #Javascript
node使用Mongoose类库实现简单的增删改查
Nov 08 #Javascript
webpack4+express+mongodb+vue实现增删改查的示例
Nov 08 #Javascript
Echarts之悬浮框中的数据排序问题
Nov 08 #Javascript
Jquery和CSS实现选择框重置按钮功能
Nov 08 #jQuery
基于React Native 0.52实现轮播图效果
Aug 25 #Javascript
You might like
简单介绍下 PHP5 中引入的 MYSQLI的用途
2007/03/19 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
jQuery实用技巧必备(中)
2015/11/03 Javascript
jQuery实现边框动态效果的实例代码
2016/09/23 Javascript
微信小程序(应用号)简单实例应用及实例详解
2016/09/26 Javascript
vue的props实现子组件随父组件一起变化
2016/10/27 Javascript
django js 实现表格动态标序号的实例代码
2019/07/12 Javascript
JavaScript判断数组类型的方法
2019/10/23 Javascript
Vue3不支持Filters过滤器的问题
2020/09/24 Javascript
如何利用JavaScript编写一个格斗小游戏
2021/01/06 Javascript
批处理与python代码混合编程的方法
2016/05/19 Python
python数据清洗系列之字符串处理详解
2017/02/12 Python
Python的语言类型(详解)
2017/06/24 Python
Python识别快递条形码及Tesseract-OCR使用详解
2019/07/15 Python
如何基于Python实现数字类型转换
2020/02/07 Python
Python流程控制语句的深入讲解
2020/06/15 Python
Python字符串及文本模式方法详解
2020/09/10 Python
浅谈html5 响应式布局
2014/12/24 HTML / CSS
美国知名男士服饰品牌:Brooks Brothers(布克兄弟)
2016/08/25 全球购物
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
文职个人求职信范文
2013/09/23 职场文书
高三毕业典礼主持词
2014/03/27 职场文书
个人求职自荐信范文
2014/06/20 职场文书
八荣八耻的活动方案
2014/08/16 职场文书
购房协议书范本
2014/10/02 职场文书
2015年收银工作总结范文
2015/04/01 职场文书
2015年宣传思想工作总结
2015/05/22 职场文书
茶花女读书笔记
2015/06/29 职场文书
2016年劳模先进事迹材料
2016/02/25 职场文书
2016年共产党员个人承诺书
2016/03/24 职场文书
小学生节约用水倡议书
2019/08/12 职场文书
聊聊pytorch测试的时候为何要加上model.eval()
2021/05/23 Python
Java 在生活中的 10 大应用
2021/11/02 Java/Android
CDPR谈《巫师》新作用虚幻5原因 称不会为Epic独占
2022/04/06 其他游戏
《总之就是很可爱》新作短篇动画《总之就是很可爱~制服~》将于2022年夏天播出
2022/04/07 日漫
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android