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 相关文章推荐
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
Aug 22 Javascript
JavaScript中定义类的方式详解
Jan 07 Javascript
jQuery 出现Cannot read property ‘msie’ of undefined错误的解决方法
Nov 23 Javascript
javascript设计模式之单体模式学习笔记
Feb 15 Javascript
纯JS实现轮播图
Feb 22 Javascript
详解VueJs异步动态加载块
Mar 09 Javascript
zTree获取当前节点的下一级子节点数实例
Sep 05 Javascript
mint-ui 时间插件使用及获取选择值的方法
Feb 09 Javascript
浅谈vue-cli 3.0.x 初体验
Apr 11 Javascript
Weex开发之地图篇的具体使用
Oct 16 Javascript
在vue中实现嵌套页面(iframe)
Jul 30 Javascript
Vue中避免滥用this去读取data中数据
Mar 02 Vue.js
深入解析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
又一个php 分页类实现代码
2009/12/03 PHP
PHP中auto_prepend_file与auto_append_file用法实例分析
2014/09/22 PHP
php使用curl获取https请求的方法
2015/02/11 PHP
用JTrackBar实现的模拟苹果风格的滚动条
2007/08/06 Javascript
锋利的jQuery 第三章章节总结的例子
2010/03/23 Javascript
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
基于jQuery的可用于选项卡及幻灯的切换插件
2011/03/28 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
js 得到文件后缀(通过正则实现)
2013/07/08 Javascript
jquery中ajax跨域方法实例分析
2015/12/18 Javascript
详解Angularjs中的依赖注入
2016/03/11 Javascript
基于javascript编写简单日历
2016/05/02 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
基于JQuery和原生JavaScript实现网页定位导航特效
2017/04/03 jQuery
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
iview日期控件,双向绑定日期格式的方法
2018/03/15 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
Python模块包中__init__.py文件功能分析
2016/06/14 Python
python实现将读入的多维list转为一维list的方法
2018/06/28 Python
Python装饰器基础概念与用法详解
2018/12/22 Python
python操作小程序云数据库实现简单的增删改查功能
2019/06/06 Python
Python实现微信好友的数据分析
2019/12/16 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
tensorflow与numpy的版本兼容性问题的解决
2021/01/08 Python
大学生军训感想
2014/02/16 职场文书
手机银行营销方案
2014/03/14 职场文书
《月球之谜》教学反思
2014/04/10 职场文书
超市优秀员工事迹材料
2014/05/01 职场文书
工作作风整顿个人剖析材料
2014/10/11 职场文书
奖学金感谢信
2015/01/21 职场文书
2016年暑期教师培训心得体会
2016/01/09 职场文书
PyTorch 如何自动计算梯度
2021/05/23 Python
浅析Python OpenCV三种滤镜效果
2022/04/11 Python