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 相关文章推荐
Flash+XML滚动新闻代码 无图片 附源码下载
Nov 22 Javascript
javaScript 读取和设置文档元素的样式属性
Apr 14 Javascript
用JQuery 实现AJAX加载XML并解析的脚本
Jul 25 Javascript
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
Mar 05 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
Mar 13 Javascript
javascript打开word文档的方法
Apr 16 Javascript
微信小程序 Audio API详解及实例代码
Sep 30 Javascript
vue.js指令v-model实现方法
Dec 05 Javascript
webpack踩坑之路图片的路径与打包
Sep 05 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
简单了解JS打开url的方法
Feb 21 Javascript
JavaScript定时器使用方法详解
Mar 26 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小技巧 把数组的键和值交换形成了新的数组,查找值取得键
2011/06/02 PHP
PHP 查找字符串常用函数介绍
2012/06/07 PHP
php对图像的各种处理函数代码小结
2013/07/08 PHP
yii添删改查实例
2015/11/16 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
php接口隔离原则实例分析
2019/11/11 PHP
幻宇的层模拟窗口效果-提供演示和下载
2007/01/20 Javascript
javascript网页关闭时提醒效果脚本
2008/10/22 Javascript
JavaScript学习笔记之JS事件对象
2015/01/22 Javascript
第六篇Bootstrap表格样式介绍
2016/06/21 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
2016/09/12 Javascript
axios发送post请求springMVC接收不到参数的解决方法
2018/03/05 Javascript
vue.js删除列表中的一行
2018/06/30 Javascript
浅谈TypeScript 用 Webpack/ts-node 运行的配置记录
2019/10/11 Javascript
详解小程序如何动态绑定点击的执行方法
2019/11/26 Javascript
python读写ini文件示例(python读写文件)
2014/03/25 Python
使用C#配合ArcGIS Engine进行地理信息系统开发
2016/02/19 Python
Python 2与Python 3版本和编码的对比
2017/02/14 Python
简述:我为什么选择Python而不是Matlab和R语言
2017/11/14 Python
python实现教务管理系统
2018/03/12 Python
python利用高阶函数实现剪枝函数
2018/03/20 Python
解决python升级引起的pip执行错误的问题
2018/06/12 Python
Python UnboundLocalError和NameError错误根源案例解析
2018/10/31 Python
Python Matplotlib实现三维数据的散点图绘制
2019/03/19 Python
Python使用修饰器进行异常日志记录操作示例
2019/03/19 Python
keras的三种模型实现与区别说明
2020/07/03 Python
HTML5全屏(Fullscreen)API详细介绍
2015/04/24 HTML / CSS
Onzie官网:美国时尚瑜伽品牌
2019/08/21 全球购物
用你熟悉的语言写一个连接ORACLE数据库的程序,能够完成修改和查询工作
2012/06/11 面试题
如果NULL定义成#define NULL((char *)0)难道不就可以向函数传入不加转换的NULL了吗
2012/02/15 面试题
数控专业应届生求职信
2013/11/27 职场文书
小学“向国旗敬礼”网上签名寄语活动总结
2014/09/27 职场文书
故宫的导游词
2015/01/31 职场文书
2015年社区文体活动总结
2015/03/25 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书
提取视频中的音频 Python只需要三行代码!
2021/05/10 Python