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 相关文章推荐
基于jquery的气泡提示效果
May 31 Javascript
javascript页面上使用动态时间具体实现
Mar 18 Javascript
JavaScript中的立即执行函数表达式介绍
Mar 15 Javascript
JS实现的左侧竖向滑动菜单效果代码
Oct 19 Javascript
基于jQuery实现页面搜索功能
Mar 26 Javascript
JavaScript实现经典排序算法之冒泡排序
Dec 28 Javascript
详解vue-router 命名路由和命名视图
Jun 01 Javascript
JavaScript中this关键字用法实例分析
Aug 24 Javascript
微信小程序使用swiper组件实现类3D轮播图
Aug 29 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
Dec 10 Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
Dec 25 Javascript
浅析JavaScript中的变量提升
Jun 01 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
菜鸟修复电子管记
2021/03/02 无线电
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
ThinkPHP中的常用查询语言汇总
2014/08/22 PHP
使用ltrace工具跟踪PHP库函数调用的方法
2016/04/25 PHP
老生常谈PHP面向对象之标识映射
2017/06/21 PHP
从零开始学习jQuery (三) 管理jQuery包装集
2011/02/23 Javascript
JavaScript获取多个数组的交集简单实例
2013/11/11 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
2014/03/22 Javascript
jQuery老黄历完整实现方法
2015/01/16 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
jQuery实现切换页面过渡动画效果
2015/10/29 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
2015/11/01 Javascript
js正则表达式验证邮件地址
2015/11/12 Javascript
JavaScript简单下拉菜单特效
2016/09/13 Javascript
配置nodejs环境的方法
2017/05/13 NodeJs
浅谈 vue 中的 watcher
2017/12/04 Javascript
在vue2.0中引用element-ui组件库的方法
2018/06/21 Javascript
vue路由守卫,限制前端页面访问权限的例子
2019/11/11 Javascript
探究python中open函数的使用
2016/03/01 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
2016/05/17 Python
python中找出numpy array数组的最值及其索引方法
2018/04/17 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
2018/05/24 Python
python实现键盘控制鼠标移动
2020/11/27 Python
Python二叉树的镜像转换实现方法示例
2019/03/06 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
通过代码实例了解Python sys模块
2020/09/14 Python
Python实现Appium端口检测与释放的实现
2020/12/31 Python
函授本科毕业生自我鉴定
2013/10/16 职场文书
学生会主席事迹材料
2014/01/28 职场文书
建筑安全员岗位职责
2014/03/13 职场文书
心理学培训心得体会
2016/01/22 职场文书