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 相关文章推荐
LBS blog sql注射漏洞[All version]-官方已有补丁
Aug 26 Javascript
javascript 检测浏览器类型和版本的代码
Sep 15 Javascript
Jquery中dialog属性小记
Sep 03 Javascript
JavaScript中的pow()方法使用详解
Jun 15 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
Aug 26 Javascript
关于js原型的面试题讲解
Sep 25 Javascript
Bootstrap表单制作代码
Mar 17 Javascript
JavaScript数据结构之二叉树的删除算法示例
Apr 13 Javascript
微信小程序实现表单校验功能
Mar 30 Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
Feb 18 jQuery
js事件机制----捕获与冒泡机制实例分析
May 22 Javascript
详解JavaScript数据类型和判断方法
Sep 04 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/03 新手入门
PHP执行速率优化技巧小结
2008/03/15 PHP
解析PHP中的正则表达式以及模式匹配
2013/06/19 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
2014/03/25 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
部署PHP时的4个配置修改说明
2015/10/19 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
tp5 实现列表数据根据状态排序
2019/10/18 PHP
javascript检查日期格式的函数[比较全]
2008/10/17 Javascript
一个挺有意思的Javascript小问题说明
2011/09/26 Javascript
js onclick事件传参讲解
2013/11/06 Javascript
jQuery带箭头提示框tooltips插件集锦
2014/11/17 Javascript
javascript删除数组重复元素的方法汇总
2015/06/24 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
Vue.JS入门教程之自定义指令
2016/12/08 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
vue分类筛选filter方法简单实例
2017/03/30 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
python创建只读属性对象的方法(ReadOnlyObject)
2013/02/10 Python
详解flask表单提交的两种方式
2018/07/21 Python
python读取Excel实例详解
2018/08/17 Python
Python3.5 Pandas模块之Series用法实例分析
2019/04/23 Python
对django views中 request, response的常用操作详解
2019/07/17 Python
numpy:找到指定元素的索引示例
2019/11/26 Python
Python编写memcached启动脚本代码实例
2020/08/14 Python
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
东方通信股份有限公司VC面试题
2014/08/27 面试题
护士节活动总结
2014/08/29 职场文书
优秀共青团员事迹材料
2014/12/25 职场文书
财务总监岗位职责范本
2015/04/03 职场文书
反腐倡廉观后感
2015/06/08 职场文书
污染环境建议书
2015/09/14 职场文书
2016年情人节广告语
2016/01/28 职场文书