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 相关文章推荐
js隐藏与显示回到顶部按钮及window.onscroll事件应用
Jan 25 Javascript
js日期相关函数总结分享
Oct 15 Javascript
Jquery遍历节点的方法小集
Jan 22 Javascript
javascript实现限制上传文件大小
Feb 06 Javascript
浅谈javascript中call()、apply()、bind()的用法
Apr 20 Javascript
JavaScript中常见的字符串操作函数及用法汇总
May 04 Javascript
使用JQuery 加载页面时调用JS的实现方法
May 30 Javascript
vue 2.0路由之路由嵌套示例详解
May 08 Javascript
vue调试工具vue-devtools安装及使用方法
Nov 07 Javascript
Node.JS在命令行中检查Chrome浏览器是否安装并打开指定网址
May 21 Javascript
element 中 el-menu 组件的无限极循环思路代码详解
Apr 26 Javascript
vue使用axios实现excel文件下载的功能
Jul 16 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
php去除换行符的方法小结(PHP_EOL变量的使用)
2013/02/16 PHP
PHP对MongoDB[NoSQL]数据库的操作
2013/03/01 PHP
Zend Framework框架路由机制代码分析
2016/03/22 PHP
php封装json通信接口详解及实例
2017/03/07 PHP
PHP+iframe模拟Ajax上传文件功能示例
2019/07/02 PHP
AngularJS基础知识
2014/12/21 Javascript
Javascript基础教程之for循环
2015/01/18 Javascript
JS转换HTML转义符的方法
2016/08/24 Javascript
EditPlus 正则表达式 实战(3)
2016/12/15 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
ECMAScript6变量的解构赋值实例详解
2017/09/19 Javascript
Vue $emit $refs子父组件间方法的调用实例
2018/09/12 Javascript
微信小程序onLaunch异步,首页onLoad先执行?
2018/09/20 Javascript
详解JS浏览器事件循环机制
2019/03/27 Javascript
vue中 v-for循环的用法详解
2020/02/19 Javascript
解决node终端下运行js文件不支持ES6语法
2020/04/04 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
node.js通过url读取文件
2020/10/16 Javascript
[06:53]2018DOTA2国际邀请赛寻真——为复仇而来的Newbee
2018/08/15 DOTA
python抽象基类用法实例分析
2015/06/04 Python
Python中的with语句与上下文管理器学习总结
2016/06/28 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
python+opencv实现高斯平滑滤波
2020/07/21 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
Python中输入和输出(打印)数据实例方法
2019/10/13 Python
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
一套Delphi的笔试题二
2013/05/11 面试题
项目经理岗位职责
2013/11/11 职场文书
九年级数学教学反思
2014/02/02 职场文书
会计与审计专业自荐信范文
2014/03/15 职场文书
农业局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
党支部三会一课计划
2014/09/24 职场文书
公司租房协议书范本
2014/10/08 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
Python 的 sum() Pythonic 的求和方法详细
2021/10/16 Python