優雅地書寫回調——Promise

第一,來談jquery下的Promisejavascript

本來寫一個動畫是這樣子的,回調函數嵌套,很是不優雅:java

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

使用了jquery的Promise對象後,優雅多了:jquery

<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 方法。ajax

promise對象常見的方法有三個 : done , fail , then 。promise

好比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對象post

舉個例子:動畫

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方法綁定的回調函數。spa

再舉個例子:code

 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時調用。其中,第二個函數是可選的,不必定要提供。

相關文章
相關標籤/搜索