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 相关文章推荐
Array.prototype.concat不是通用方法反驳[译]
Sep 20 Javascript
node.js中的fs.statSync方法使用说明
Dec 16 Javascript
移动端js触摸事件详解
Sep 18 Javascript
JavaScript中定时控制Throttle、Debounce和Immediate详解
Nov 17 Javascript
jQuery Validate设置onkeyup验证的实例代码
Dec 09 Javascript
浅谈对Angular中的生命周期钩子的理解
Jul 31 Javascript
JS实现电商放大镜效果
Aug 24 Javascript
基于复选框demo(分享)
Sep 27 Javascript
无限循环轮播图之运动框架(原生JS实现)
Oct 01 Javascript
还不懂递归?读完这篇文章保证你会懂
Jul 29 Javascript
JavaScript中this的全面解析及常见实例
May 14 Javascript
php结合js实现多条件组合查询
May 28 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
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
php堆排序(heapsort)练习
2013/11/13 PHP
php在apache环境下实现gzip配置方法
2015/04/02 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
用js实现随机返回数组的一个元素
2007/08/13 Javascript
jQuery Ajax之$.get()方法和$.post()方法
2009/10/12 Javascript
防止浏览器记住用户名及密码的简单实用方法
2013/04/22 Javascript
js获取下拉列表框中的value和text的值示例代码
2014/01/11 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
JS+CSS实现的经典tab选项卡效果代码
2015/09/16 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
js实现一个可以兼容PC端和移动端的div拖动效果实例
2016/12/09 Javascript
Vue.js基础学习之class与样式绑定
2017/03/20 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
2017/06/30 Javascript
JS实现按钮颜色切换效果
2020/09/05 Javascript
使用Jenkins部署React项目的方法步骤
2019/03/11 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
2020/07/19 Javascript
[01:07:13]TNC vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python中map()函数的使用方法示例
2017/09/29 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
详解一种用django_cache实现分布式锁的方式
2019/09/01 Python
python encrypt 实现AES加密的实例详解
2020/02/20 Python
python画图常规设置方式
2020/03/05 Python
Python configparser模块操作代码实例
2020/06/08 Python
python3中for循环踩过的坑记录
2020/12/14 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
html5使用canvas绘制文字特效
2014/12/15 HTML / CSS
励志演讲稿大全
2014/08/21 职场文书
校园广播稿100字
2014/10/06 职场文书
教育合作协议范本
2014/10/17 职场文书
毕业论文致谢范文
2015/05/14 职场文书
python实现自动化群控的步骤
2021/04/11 Python
golang 实现两个结构体复制字段
2021/04/28 Golang
利用python调用摄像头的实例分析
2021/06/07 Python
基于Python编写一个监控CPU的应用系统
2022/06/25 Python