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 相关文章推荐
PJBlog插件 防刷新的在线播放器
Oct 25 Javascript
使图片旋转的3种解决方案
Nov 21 Javascript
javascript删除元素节点removeChild()用法实例
May 26 Javascript
jQuery实现一个简单的轮播图
Feb 19 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
May 08 Javascript
Node.js进阶之核心模块https入门
May 23 Javascript
详解在网页上通过JS实现文本的语音朗读
Mar 28 Javascript
基于vue开发微信小程序mpvue-docs跳转页面功能
Apr 10 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
Apr 23 Javascript
微信小程序环境下将文件上传到OSS的方法步骤
May 31 Javascript
JavaScript遍历数组和对象的元素简单操作示例
Jul 09 Javascript
Vue实现多标签选择器
Nov 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
$_GET['goods_id']+0 的使用详解
2013/06/06 PHP
PHP图片裁剪函数(保持图像不变形)
2014/05/04 PHP
php延迟静态绑定实例分析
2015/02/08 PHP
php中header设置常见文件类型的content-type
2015/06/23 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
2015/12/21 PHP
php基于dom实现读取图书xml格式数据的方法
2017/02/03 PHP
实现laravel 插入操作日志到数据库的方法
2019/10/11 PHP
laravel 5.3 单用户登录简单实现方法
2019/10/14 PHP
js计数器代码
2006/11/04 Javascript
jQuery中对节点进行操作的相关介绍
2013/04/16 Javascript
通过JQuery实现win8一样酷炫的动态磁贴效果(示例代码)
2013/07/13 Javascript
js判断输入是否为数字的具体实例
2013/08/03 Javascript
jquery常用特效方法使用示例
2014/04/25 Javascript
node.js中的fs.readFile方法使用说明
2014/12/15 Javascript
如何在node的express中使用socket.io
2014/12/15 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
js enter键激发事件实例代码
2016/08/17 Javascript
浅谈jquery选择器 :first与:first-child的区别
2016/11/20 Javascript
js正则表达式验证表单【完整版】
2017/03/06 Javascript
es6学习之解构时应该注意的点
2017/08/29 Javascript
vue params、query传参使用详解
2017/09/12 Javascript
JS实现简单tab选项卡切换
2019/10/25 Javascript
vue 使用 canvas 实现手写电子签名
2020/03/06 Javascript
在Python中使用base64模块处理字符编码的教程
2015/04/28 Python
Python使用Django实现博客系统完整版
2020/09/29 Python
python+selenium实现自动抢票功能实例代码
2018/11/23 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
详解用Python进行时间序列预测的7种方法
2020/03/13 Python
Python可以实现栈的结构吗
2020/05/27 Python
python语言实现贪吃蛇游戏
2020/11/13 Python
应届生求职简历的自我评价怎么写
2013/10/23 职场文书
工厂保洁员岗位职责
2013/12/04 职场文书
2014大学生中国梦主题教育学习思想汇报
2014/09/10 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
交警失职检讨书
2015/01/26 职场文书
PHP设计模式(观察者模式)
2021/07/07 PHP