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 动态table添加colspan\rowspan 参数的方法
Jul 25 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
Mar 02 Javascript
JS localStorage实现本地缓存的方法
Jun 22 Javascript
css结合js制作下拉菜单示例代码
Feb 27 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
Apr 16 Javascript
简单实现js放大镜效果
Jul 24 Javascript
搭建基于express框架运行环境的方法步骤
Nov 15 Javascript
JS实现求5的阶乘示例
Jan 21 Javascript
JavaScript解析机制与闭包原理实例详解
Mar 08 Javascript
原生JS使用Canvas实现拖拽式绘图功能
Jun 05 Javascript
在vue中利用全局路由钩子给url统一添加公共参数的例子
Nov 01 Javascript
javascript实现前端分页功能
Nov 26 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的日期与时间函数技巧
2008/04/24 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
PHP PDOStatement::setFetchMode讲解
2019/02/03 PHP
javascript的字符串按引用复制和传递,按值来比较介绍与应用
2012/12/28 Javascript
JQUERY 获取IFrame中对象及获取其父窗口中对象示例
2013/08/19 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
2014/04/29 Javascript
批量修改标签css样式以input标签为例
2014/07/31 Javascript
JS动态创建DOM元素的方法
2015/06/09 Javascript
JavaScript中数据结构与算法(三):链表
2015/06/19 Javascript
全面解析DOM操作和jQuery实现选项移动操作代码分享
2016/06/07 Javascript
JS弹性运动实现方法分析
2016/12/15 Javascript
js常用DOM方法详解
2017/02/04 Javascript
vue2.0实现导航菜单切换效果
2017/05/08 Javascript
微信小程序实现打开内置地图功能【附源码下载】
2017/12/07 Javascript
Node.js创建HTTP文件服务器的使用示例
2018/05/11 Javascript
原生JS实现随机点名项目的实例代码
2019/04/30 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
微信小程序向Java后台传输参数的方法实现
2020/12/10 Javascript
[01:20]DOTA2 2017国际邀请赛冠军之路无止竞
2017/06/19 DOTA
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python的Flask框架应用程序实现使用QQ账号登录的方法
2016/06/07 Python
python3+PyQt5实现使用剪贴板做复制与粘帖示例
2017/01/24 Python
Python实现合并两个列表的方法分析
2018/05/28 Python
python遍历文件夹,指定遍历深度与忽略目录的方法
2018/07/11 Python
python pytest进阶之fixture详解
2019/06/27 Python
python 中xpath爬虫实例详解
2019/08/26 Python
Python 实现自动导入缺失的库
2019/10/29 Python
Python实现将蓝底照片转化为白底照片功能完整实例
2019/12/13 Python
django实现更改数据库某个字段以及字段段内数据
2020/03/31 Python
新西兰演唱会和体育门票网站:Ticketmaster新西兰
2017/10/07 全球购物
有影响力的品牌之家:Our Social Collective
2019/06/08 全球购物
美国Max仓库:Max Warehouse
2020/05/31 全球购物
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
物流仓管员工作职责
2014/01/06 职场文书
自我鉴定书
2014/03/24 职场文书
新学期主题班会
2015/08/17 职场文书