JS異步那些事 三 (Promise)

JS異步那些事 一 (基礎(chǔ)知識(shí))
JS異步那些事 二 (分布式事件)
JS異步那些事 三 (Promise)
JS異步那些事 四(HTML 5 Web Workers)
JS異步那些事 五 (異步腳本加載)

Promise,Deferred 對(duì)象

前戲

先來(lái)談?wù)刯query中的promise的使用,來(lái)看一個(gè)例子
原本寫一個(gè)小動(dòng)畫我們可能是這樣的

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

但是如果我們使用promis對(duì)象的話稻据,就可以使得代碼更加簡(jiǎn)單易懂

<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>

看了上面的例子大概對(duì)promise的作用有一定的了解了吧槽华,那就來(lái)說(shuō)說(shuō)promis的原理吧

Promise對(duì)象方法

對(duì)于DOM吃度,動(dòng)畫项阴,ajax相關(guān)方法喊式,都可以使用 promise 方法锌奴。調(diào)用 promise 方法兽狭,返回的是 promise 對(duì)象。可以鏈?zhǔn)秸{(diào)用 promise 方法箕慧。

比如jquery中的ajax的 $.post $.get $.ajax 等方法服球,實(shí)際上都是默認(rèn)調(diào)用了promise方法,然后返回了一個(gè)promise對(duì)象

promise對(duì)象常見的方法有三個(gè) : done 颠焦, fail 斩熊, then 。

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

jquery 這里的接口方法太多了伐庭,就跟早期的事件方法綁定一樣粉渠, live , delegate 圾另, bind 渣叛,最終還是歸為 on

deferred對(duì)象方法

deferred 對(duì)象呢,也就是使用 $.Deferred() 方法盯捌,以及 $.when() 等方法創(chuàng)造出來(lái)的對(duì)象淳衙,它可以理解為一個(gè)升級(jí)版特殊的的promise對(duì)象
來(lái)看看一個(gè)例子

  <script type="text/javascript"> 
  var  promisepbj = new $.Deferred();

     promisepbj.done(function() {
      console.log('haha,done');
    }).fail(function() {
      console.log('失敗了');
    }).always(function(res) {
      console.log('我總是被執(zhí)行啦');
    });

    //使用resolve或者reject就可以調(diào)用defferred對(duì)象了
    promisepobj.resolve();
    //promisepobj.reject();

resolve 方法會(huì)觸發(fā) done 的回調(diào)執(zhí)行, reject 會(huì)觸發(fā) fail 的回調(diào)饺著,對(duì)于 always 方法,deferred 對(duì)象,無(wú)論是 resolve 還是 reject 箫攀,都會(huì)觸發(fā)該方法的回調(diào)。

ES6 Promise

前面講了很多jquery的promise實(shí)現(xiàn)幼衰,$.Deferred 和 ES2015 的 Promise 是不同的東西靴跛,因?yàn)榍罢卟环?Promises/A+ 規(guī)范。 Promise 對(duì)象在 EMCAScript 2015 當(dāng)中已經(jīng)成為標(biāo)準(zhǔn)《上現(xiàn)在要來(lái)談?wù)勸R上要成為主流趨勢(shì)的es6原生promise對(duì)象梢睛,首先貼一個(gè)很詳細(xì)的es6 promise的小書,基本你知道的不知道都在里面 http://liubin.org/promises-book/#introduction识椰,

把promise解釋的很清楚的文章很多绝葡,我自認(rèn)為我寫不到他們那么好,索性干脆把阮一峰大神的文章貼出來(lái) http://es6.ruanyifeng.com/#docs/promise
我就來(lái)個(gè)簡(jiǎn)化版本的吧腹鹉,用最短的字?jǐn)?shù)來(lái)入個(gè)門藏畅。

定義:

謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器功咒,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果愉阎。
特點(diǎn):

  1. 有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成力奋,又稱Fulfilled)和Rejected(已失敯竦)。
  2. 一旦狀態(tài)改變景殷,就不會(huì)再變溅呢,任何時(shí)候都可以得到這個(gè)結(jié)果锉走。Promise對(duì)象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected藕届。只要這兩種情況發(fā)生,狀態(tài)就凝固了

基本用法

  <script type="text/javascript"> 
var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
</script>

Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)亭饵,該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject休偶。

  <script type="text/javascript"> 
function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}

timeout(100).then((value) => {
  console.log(value);
});
</script>

上面代碼中,timeout方法返回一個(gè)Promise實(shí)例辜羊,表示一段時(shí)間以后才會(huì)發(fā)生的結(jié)果踏兜。過(guò)了指定的時(shí)間(ms參數(shù))以后,Promise實(shí)例的狀態(tài)變?yōu)镽esolved八秃,就會(huì)觸發(fā)then方法綁定的回調(diào)函數(shù)碱妆。

異常處理

異常處理一直是回調(diào)的難題,而promise提供了非常方便的catch方法:在一次promise調(diào)用中昔驱,任何的環(huán)節(jié)發(fā)生reject疹尾,都可以在最終的catch中捕獲到:

Promise.resolve().then(function(){
    return loadImage(img1);
}).then(function(){
    return loadImage(img2);
}).then(function(){
    return loadImage(img3);
}).catch(function(err){
    //錯(cuò)誤處理
})

基本的 api

Promise.resolve()
Promise.reject()
Promise.prototype.then()
Promise.prototype.catch()
Promise.all()
Promise.race()

小結(jié)

具體的很多的用法可以參考阮一峰的 http://es6.ruanyifeng.com/#docs/promise 入門教程,還有就是上面提到的電子書 http://liubin.org/promises-book/#introduction骤肛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纳本,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腋颠,更是在濱河造成了極大的恐慌繁成,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淑玫,死亡現(xiàn)場(chǎng)離奇詭異巾腕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)絮蒿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門尊搬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人土涝,你說(shuō)我怎么就攤上這事毁嗦。” “怎么了回铛?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵狗准,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我茵肃,道長(zhǎng)腔长,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任验残,我火速辦了婚禮捞附,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己鸟召,他們只是感情好胆绊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著欧募,像睡著了一般压状。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跟继,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天种冬,我揣著相機(jī)與錄音,去河邊找鬼舔糖。 笑死娱两,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的金吗。 我是一名探鬼主播十兢,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼摇庙!你這毒婦竟也來(lái)了纪挎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤跟匆,失蹤者是張志新(化名)和其女友劉穎异袄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玛臂,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烤蜕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了迹冤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讽营。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖泡徙,靈堂內(nèi)的尸體忽然破棺而出橱鹏,到底是詐尸還是另有隱情,我是刑警寧澤堪藐,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布莉兰,位于F島的核電站,受9級(jí)特大地震影響礁竞,放射性物質(zhì)發(fā)生泄漏糖荒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一模捂、第九天 我趴在偏房一處隱蔽的房頂上張望捶朵。 院中可真熱鬧蜘矢,春花似錦、人聲如沸综看。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)红碑。三九已至舞吭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間句喷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工兔毙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唾琼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓澎剥,卻偏偏與公主長(zhǎng)得像锡溯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哑姚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容