首页 > 代码库 > 优雅地书写回调——Promise

优雅地书写回调——Promise

第一,来谈jquery下的Promise

原本写一个动画是这样子的,回调函数嵌套,非常不优雅:

<script type="text/javascript"> 
$(‘.animateEle‘).animate({
  opacity:‘.5‘
}, 4000,function(){
  $(‘.animateEle2‘).animate({
    width:‘100px‘
  },2000,function(){
    $(‘.animateEle3‘).animate({
      height:‘0‘
    },2000);
  });
});
</script> 

使用了jquery的Promise对象后,优雅多了:

<script type="text/javascript"> 
var animate1 = function() {
  return $(‘.animateEle1‘).animate({opacity:‘.5‘},4000).promise();
};
var animate2 = function() {
  return $(‘.animateEle2‘).animate({width:‘100px‘},2000).promise();
};
var animate3 = function(){
  return $(‘.animateEle3‘).animate({height:‘0‘},2000).promise();
};
$.when(animate1()).then(animate2).then(animate3);
</script>

对于DOM,动画,ajax相关方法,都可以使用 promise 方法。调用 promise 方法,返回的是 promise 对象。可以链式调用 promise 方法。

promise对象常见的方法有三个 : done , fail , then 。

比如jquery中的ajax的 $.post $.get $.ajax 等方法,实际上都是默认调用了promise方法,然后返回了一个promise对象

<script type="text/javascript"> 
$.get(‘/‘,{}).done(function(data){
    console.log(‘success‘);
}).fail(function(){
    console.log(‘fail‘);
});
</script>

第二,ECMA6提供了Promise对象

举个例子:

1 function timeout(ms) {
2   return new Promise((resolve, reject) => {
3     setTimeout(resolve, ms, ‘done‘);
4   });
5 }
6 
7 timeout(100).then((value) => {
8   console.log(value);
9 });

上面代码中,timeout方法返回一个Promise实例。resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”。过了指定的时间(ms参数)以后,Promise实例的状态变为Resolved,就会触发then方法绑定的回调函数。

再举个例子:

 1 let promise = new Promise(function(resolve, reject) {
 2   console.log(‘Promise‘);
 3   resolve();
 4 });
 5 
 6 promise.then(function() {
 7   console.log(‘Resolved.‘);
 8 });
 9 
10 console.log(‘Hi!‘);
11 
12 // Promise
13 // Hi!
14 // Resolved

上面代码中,Promise新建后立即执行,所以首先输出的是“Promise”。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以“Resolved”最后输出。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。

优雅地书写回调——Promise