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中的parseInt使用技巧
Sep 03 Javascript
js removeChild 障眼法 可能出现的错误
Oct 06 Javascript
javascript 定义新对象方法
Feb 20 Javascript
用jquery方法操作radio使其默认选项是否
Sep 10 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
Sep 29 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
Dec 18 Javascript
JavaScript两种跨域技术全面介绍
Apr 16 Javascript
Canvas实现动态的雪花效果
Feb 13 Javascript
JS获取填报扩展单元格控件的值的解决办法
Jul 14 Javascript
用最少的JS代码写出贪吃蛇游戏
Jan 12 Javascript
Vue 莹石摄像头直播视频实例代码
Aug 31 Javascript
Vue Object 的变化侦测实现代码
Apr 15 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
肝肠寸断了解下!盘点史上最伤心的十大动漫
2020/03/04 日漫
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
PHP中图片等比缩放的实例
2013/03/24 PHP
ThinkPHP3.1.3版本新特性概述
2014/06/19 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
ThinkPHP实现的rsa非对称加密类示例
2018/05/29 PHP
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
jQuery Autocomplete自动完成插件
2010/07/17 Javascript
jquery 插件学习(五)
2012/08/06 Javascript
Java 正则表达式学习总结和一些小例子
2012/09/13 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
解析js如何获取当前url中的参数值并复制给input
2013/06/23 Javascript
javascript full screen 全屏显示页面元素的方法
2013/09/27 Javascript
js 获取、清空input type=&quot;file&quot;的值(示例代码)
2013/12/24 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
js处理表格对table进行修饰
2014/05/26 Javascript
详解JavaScript的回调函数
2015/11/20 Javascript
Node.js connect ECONNREFUSED错误解决办法
2016/09/15 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
jQuery中用on绑定事件时需注意的事项
2017/03/19 Javascript
详解vue事件对象、冒泡、阻止默认行为
2017/03/20 Javascript
详解NodeJS Https HSM双向认证实现
2019/03/12 NodeJs
基于p5.js 2D图像接口的扩展(交互实现)
2020/11/30 Javascript
python自动zip压缩目录的方法
2015/06/28 Python
详解python 爬取12306验证码
2019/05/10 Python
浅谈python 中类属性共享的问题
2019/07/02 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
英国最受欢迎的手表网站:Watch Shop
2016/10/21 全球购物
AT&T Wireless:手机、无限数据计划和配件
2018/06/03 全球购物
UNIONBAY官网:美国青少年服装品牌
2019/03/26 全球购物
企业优秀团员事迹材料
2014/08/20 职场文书
护士年终考核评语
2014/12/31 职场文书
学生退学证明
2015/06/23 职场文书
2019七夕节祝福语36句,快来收藏吧
2019/08/06 职场文书
实现一个简单得数据响应系统
2021/11/11 Javascript