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编写的第一人称射击游戏
Feb 25 Javascript
js类中获取外部函数名的方法与代码
Sep 12 Javascript
获取URL地址中的文件名和参数的javascript代码
Sep 02 Javascript
浅谈javascript 面向对象编程
Oct 28 Javascript
如何让div span等元素能响应键盘事件操作指南
Nov 13 Javascript
jquery.post用法关于type设置问题补充
Jan 03 Javascript
javascript日期对象格式化为字符串的实现方法
Jan 14 Javascript
用javascript实现自动输出网页文本
Jul 30 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
Sep 01 Javascript
JavaScript实现输入框(密码框)出现提示语
Jan 12 Javascript
完美实现js焦点轮播效果(一)
Mar 07 Javascript
jQuery实现图片简单轮播功能示例
Aug 13 jQuery
深入解析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 抓取新浪读书频道的小说并生成txt电子书的代码
2009/12/18 PHP
PHP 开发环境配置(Zend Studio)
2010/04/28 PHP
php 文件上传类代码
2011/08/06 PHP
ThinkPHP内置jsonRPC的缺陷分析
2014/12/18 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
php验证码实现代码(3种)
2015/09/07 PHP
php实现倒计时效果
2015/12/19 PHP
在PHP 7下安装Swoole与Yar,Yaf的方法教程
2017/06/02 PHP
javascript 跳转代码集合
2009/12/03 Javascript
可插入图片的TEXT文本框
2013/12/27 Javascript
用jQuery实现的智能隐藏、滑动效果的返回顶部代码
2014/03/18 Javascript
jQuery中height()方法用法实例
2014/12/24 Javascript
jQuery中animate用法实例分析
2015/03/09 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
基于javascript实现句子翻牌网页版小游戏
2016/03/23 Javascript
javascript实现的猜数小游戏完整实例代码
2016/05/10 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
2016/06/02 Javascript
JS递归遍历对象获得Value值方法技巧
2016/06/14 Javascript
Bootstrap轮播图学习使用
2017/02/10 Javascript
jQuery实现百度登录框的动态切换效果
2017/04/21 jQuery
浅谈Angular路由守卫
2017/08/26 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
JQuery Ajax执行跨域请求数据的解决方案
2018/12/10 jQuery
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
微信小程序实现简单购物车功能
2020/12/30 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
2021/01/19 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python通过ElementTree操作XML获取结点读取属性美化XML
2013/12/02 Python
对pandas中时间窗函数rolling的使用详解
2018/11/28 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
世界上最大的专业美容用品零售商:Sally Beauty
2017/07/02 全球购物
Bally澳大利亚官网:瑞士奢侈品牌
2018/11/01 全球购物
学生检讨书范文
2014/10/30 职场文书
党的群众路线教育实践活动个人对照检查材料(教师)
2014/11/04 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
js Proxy的原理详解
2021/05/25 Javascript