在传统的异步回调中大多都是方法里传入方法一直向函数里面深入添加
或者用 jquery 扩展的 then 方法;
举个例子:在动画连接的应用中
.ball{width: 50px;height: 50px;border-radius: 50%;margin-bottom: 10px;}
.ball1{background-color: green}
.ball2{background-color: red}
.ball3{background-color: blue}
<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('div.ball1');
var ball2 = document.querySelector('div.ball2');
var ball3 = document.querySelector('div.ball3');
function animate( ball , distance , cb){ //对象 到点的距离 回调方法
setTimeout(function(){
var marginLeft = parseInt(ball.style.marginLeft,10);
if(marginLeft === distance){ // div 的 marginLeft 走到相应的位置执行回调
cb && cb();
}else{
if(marginLeft < distance){ // 位置没到就向前走 1PX
marginLeft ++ ;
}else{
marginLeft -- ; //位置多了就回走 1px
}
ball.style.marginLeft = marginLeft + 'px';
animate(ball,distance,cb);
}
}, 13 ); //动画时间最流畅是 1 秒 60 帧 , 1000/60 = 16 左右 ,去掉 setTimeout 方法的时间,大概是 13
}
animate(ball1 , 100 , function(){
animate(ball2 , 150 ,function(){
animate(ball3 , 150 , function(){
animate(ball3 , 100 , function(){
animate(ball2 , 100 , function(){
//
})
})
})
})
})
上面的动画是,一个球走完,然后另一个球接着走,再另一个…… 一直走下去,上面的调用是在 animate 方法里不断的回调,
现在来介绍一个新的方法,Promise 方法,Promise 就像 jquery 扩展的 then 方法一样,现在不用连接 jquery 也一样可以用到
Promise 方法
Promise 方法是 es6 中新增加的方法 ,在新版本的浏览器已经可以支持,对于老版本的浏览器可以连接一个 js 也是一样的效果
老版本用 npm install bluebird 下载该插件 ,连接里面的 /node_modules/bluebird/js/browser/bluebird.js
下面是前面的例子用 Promise 方法的代码
/*promise 方法 promise是ES6处带的方法,新版浏览器已经自带有该方法
为兼容老版本,可以下载一个 bluebird
npm install bluebird
接上 <script src="./node_modules/bluebird/js/browser/bluebird.js">
然后全局就有 Promise 方法了
var Promise = window.Promise;
*/
function promiseAnimate(ball , distance){
return new Promise(function( resolve, reject){ //成功回调 失败的回调
function _animate(){ //对象 到点的距离 回调方法
setTimeout(function(){
var marginLeft = parseInt(ball.style.marginLeft,10);
if(marginLeft === distance){ // div 的 marginLeft 走到相应的位置执行回调
resolve();
}else{
if(marginLeft < distance){ // 位置没到就向前走 1PX
marginLeft ++ ;
}else{
marginLeft -- ; //位置多了就回走 1px
}
ball.style.marginLeft = marginLeft + 'px';
_animate();
}
}, 13 ); //动画时间最流畅是 1 秒 60 帧 , 1000/60 = 16 左右 ,去掉 setTimeout 方法的时间,大概是 13
}
_animate();
})
}
promiseAnimate(ball1, 100)
.then(function(){
return promiseAnimate(ball2, 150);
})
.then(function(){
return promiseAnimate(ball3, 250);
})
.then(function(){
return promiseAnimate(ball3, 200);
})
.then(function(){
return promiseAnimate(ball2, 200);
})
.then(function(){
promiseAnimate(ball1, 200);
})
把上面的 animate 方法放在 new Promise里 ,两个参数分别是传进来的 成功的回调 ,失败的回调,以上只用到一个
在调用用 then 执行回调,如果下面还有方法要接上,要把它 return 回去