我们先写出三个小球球
<style> .ball{ width:40px; height:40px; border-radius: 20px; } .ball1{ background:red; } .ball2{ background:yellow; } .ball3{ background:blue; } </style> <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>之后就是三个小球的运动
//获取三个小球 var ball1 = document.querySelector('.ball1') var ball2 = document.querySelector('.ball2') var ball3 = document.querySelector('.ball3')运动函数
function animate (ball, distance, cb) { //设置一个定时器,每13毫秒移动一像素(13毫秒是浏览器最好的兼容效果) setTimeout(function() { //获取到小球的目前位置 var marginLeft = parseInt(ball.style.marginLeft, 10) //判断小球是否达到我们预期的位置 if(marginLeft === distance) { //到了就执行我们传入的回调函数 cb && cb() }else{ //没到就继续移动 if(marginLeft < distance) { marginLeft++ }else{ marginLeft-- } //改变小球的位置变成我们加了之后一像素的位置 ball.style.marginLeft = marginLeft + 'px' //在执行函数本身 animate(ball, distance, cb) } },13) }运动的函数写好了,接下来就是调用函数了
animate(ball1, 100, function(){ animate(ball2, 200, function() { animate(ball3, 300, function() { animate(ball3, 150, function() { animate(ball2, 150, function() { animate(ball1, 150, function() { }) }) }) }) }) })这种写法就是我们正常使用回调函数进行异步的操作
结下来使用promise进行一样的操作,看看区别
首先也是写出三个小球,与上面一样,然后我们引入一个promise库,里面有定义好的promise对象
<script src='./node_modules/bluebird/js/browser/bluebird.js'></script>进入目标文件夹下,使用npm install bulebird下载
//获取到promise对象,就是bulebird暴漏出来的接口 var Promise = window.Promise //运动函数 function promiseAnimate(ball, distance) { //返回一个promise对象 return new Promise(function(resolve, reject) { function _animate () { setTimeout(function() { var marginLeft = parseInt(ball.style.marginLeft, 10) if(marginLeft === distance) { resolve() }else{ if(marginLeft < distance) { marginLeft++ }else{ marginLeft-- } ball.style.marginLeft = marginLeft + 'px' _animate() } },13) } _animate() }) }执行
promiseAnimate(ball1, 100) .then(function() { return promiseAnimate(ball2, 200) }) .then(function() { return promiseAnimate(ball3, 300) }) .then(function() { return promiseAnimate(ball3, 150) }) .then(function() { return promiseAnimate(ball2, 150) }) .then(function() { return promiseAnimate(ball1, 150) })两种写法是一样的效果
promise最大的特点就是:回调函数可以写成规范的链式调用写法,程序流程可以很清楚,接口可以实现强大功能。