中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

JavaScript Promise啟示錄
來源:易賢網 閱讀:1463 次 日期:2014-08-14 15:56:14
溫馨提示:易賢網小編為您整理了“JavaScript Promise啟示錄”,方便廣大網友查閱!

本篇,主要普及promise的用法。

一直以來,JavaScript處理異步都是以callback的方式,在前端開發領域callback機制幾乎深入人心。在設計API的時候,不管是瀏覽器廠商還是SDK開發商亦或是各種類庫的作者,基本上都已經遵循著callback的套路。

近幾年隨著JavaScript開發模式的逐漸成熟,CommonJS規范順勢而生,其中就包括提出了Promise規范,Promise完全改變了js異步編程的寫法,讓異步編程變得十分的易于理解。

在callback的模型里邊,我們假設需要執行一個異步隊列,代碼看起來可能像這樣:

view sourceprint?1 loadImg('a.jpg', function() {

2 loadImg('b.jpg', function() {

3 loadImg('c.jpg', function() {

4 console.log('all done!');

5 });

6 });

7 });

這也就是我們常說的回調金字塔,當異步的任務很多的時候,維護大量的callback將是一場災難。當今Node.js大熱,好像很多團隊都要用它來做點東西以沾沾“洋氣”,曾經跟一個運維的同學聊天,他們也是打算使用Node.js做一些事情,可是一想到js的層層回調就望而卻步。

好,扯淡完畢,下面進入正題。

Promise可能大家都不陌生,因為Promise規范已經出來好一段時間了,同時Promise也已經納入了ES6,而且高版本的chrome、firefox瀏覽器都已經原生實現了Promise,只不過和現如今流行的類Promise類庫相比少些API。

所謂Promise,字面上可以理解為“承諾”,就是說A調用B,B返回一個“承諾”給A,然后A就可以在寫計劃的時候這么寫:當B返回結果給我的時候,A執行方案S1,反之如果B因為什么原因沒有給到A想要的結果,那么A執行應急方案S2,這樣一來,所有的潛在風險都在A的可控范圍之內了。

上面這句話,翻譯成代碼類似:

view sourceprint?1 var resB = B();

2 var runA = function() {

3 resB.then(execS1, execS2);

4 };

5 runA();

只看上面這行代碼,好像看不出什么特別之處。但現實情況可能比這個復雜許多,A要完成一件事,可能要依賴不止B一個人的響應,可能需要同時向多個人詢問,當收到所有的應答之后再執行下一步的方案。最終翻譯成代碼可能像這樣:

view sourceprint?01 var resB = B();

02 var resC = C();

03 ...

04

05 var runA = function() {

06 reqB

07 .then(resC, execS2)

08 .then(resD, execS3)

09 .then(resE, execS4)

10 ...

11 .then(execS1);

12 };

13

14 runA();

在這里,當每一個被詢問者做出不符合預期的應答時都用了不同的處理機制。事實上,Promise規范沒有要求這樣做,你甚至可以不做任何的處理(即不傳入then的第二個參數)或者統一處理。

好了,下面我們來認識下Promise/A+規范:

一個promise可能有三種狀態:等待(pending)、已完成(fulfilled)、已拒絕(rejected)

一個promise的狀態只可能從“等待”轉到“完成”態或者“拒絕”態,不能逆向轉換,同時“完成”態和“拒絕”態不能相互轉換

promise必須實現then方法(可以說,then就是promise的核心),而且then必須返回一個promise,同一個promise的then可以調用多次,并且回調的執行順序跟它們被定義時的順序一致

then方法接受兩個參數,第一個參數是成功時的回調,在promise由“等待”態轉換到“完成”態時調用,另一個是失敗時的回調,在promise由“等待”態轉換到“拒絕”態時調用。同時,then可以接受另一個promise傳入,也接受一個“類then”的對象或方法,即thenable對象。

可以看到,Promise規范的內容并不算多,大家可以試著自己實現以下Promise。

以下是筆者自己在參考許多類Promise庫之后簡單實現的一個Promise,代碼請移步promiseA。

簡單分析下思路:

構造函數Promise接受一個函數resolver,可以理解為傳入一個異步任務,resolver接受兩個參數,一個是成功時的回調,一個是失敗時的回調,這兩參數和通過then傳入的參數是對等的。

其次是then的實現,由于Promise要求then必須返回一個promise,所以在then調用的時候會新生成一個promise,掛在當前promise的_next上,同一個promise多次調用都只會返回之前生成的_next。

由于then方法接受的兩個參數都是可選的,而且類型也沒限制,可以是函數,也可以是一個具體的值,還可以是另一個promise。下面是then的具體實現:

view sourceprint?01 Promise.prototype.then = function(resolve, reject) {

02 var next = this._next || (this._next = Promise());

03 var status = this.status;

04 var x;

05

06 if('pending' === status) {

07 isFn(resolve) && this._resolves.push(resolve);

08 isFn(reject) && this._rejects.push(reject);

09 return next;

10 }

11

12 if('resolved' === status) {

13 if(!isFn(resolve)) {

14 next.resolve(resolve);

15 } else {

16 try {

17 x = resolve(this.value);

18 resolveX(next, x);

19 } catch(e) {

20 this.reject(e);

21 }

22 }

23 return next;

24 }

25

26 if('rejected' === status) {

27 if(!isFn(reject)) {

28 next.reject(reject);

29 } else {

30 try {

31 x = reject(this.reason);

32 resolveX(next, x);

33 } catch(e) {

34 this.reject(e);

35 }

36 }

37 return next;

38 }

39 };

這里,then做了簡化,其他promise類庫的實現比這個要復雜得多,同時功能也更多,比如還有第三個參數——notify,表示promise當前的進度,這在設計文件上傳等時很有用。對then的各種參數的處理是最復雜的部分,有興趣的同學可以參看其他類Promise庫的實現。

在then的基礎上,應該還需要至少兩個方法,分別是完成promise的狀態從pending到resolved或rejected的轉換,同時執行相應的回調隊列,即resolve()和reject()方法。

到此,一個簡單的promise就設計完成了,下面簡單實現下兩個promise化的函數:

view sourceprint?01 function sleep(ms) {

02 return function(v) {

03 var p = Promise();

04

05 setTimeout(function() {

06 p.resolve(v);

07 }, ms);

08

09 return p;

10 };

11 };

12

13 function getImg(url) {

14 var p = Promise();

15 var img = new Image();

16

17 img.onload = function() {

18 p.resolve(this);

19 };

20

21 img.onerror = function(err) {

22 p.reject(err);

23 };

24

25 img.url = url;

26

27 return p;

28 };

由于Promise構造函數接受一個異步任務作為參數,所以getImg還可以這樣調用:

view sourceprint?01 function getImg(url) {

02 return Promise(function(resolve, reject) {

03 var img = new Image();

04

05 img.onload = function() {

06 resolve(this);

07 };

08

09 img.onerror = function(err) {

10 reject(err);

11 };

12

13 img.url = url;

14 });

15 };

接下來(見證奇跡的時刻),假設有一個BT的需求要這么實現:異步獲取一個json配置,解析json數據拿到里邊的圖片,然后按順序隊列加載圖片,沒張圖片加載時給個loading效果

view sourceprint?01 function addImg(img) {

02 $('#list').find('> li:last-child').html('').append(img);

03 };

04

05 function prepend() {

06 $('<li>')

07 .html('loading...')

08 .appendTo($('#list'));

09 };

10

11 function run() {

12 $('#done').hide();

13 getData('map.json')

14 .then(function(data) {

15 $('h4').html(data.name);

16

17 return data.list.reduce(function(promise, item) {

18 return promise

19 .then(prepend)

20 .then(sleep(1000))

21 .then(function() {

22 return getImg(item.url);

23 })

24 .then(addImg);

25 }, Promise.resolve());

26 })

27 .then(sleep(300))

28 .then(function() {

29 $('#done').show();

30 });

31 };

32

33 $('#run').on('click', run);

這里的sleep只是為了看效果加的,可猛擊查看demo!當然,Node.js的例子可查看這里。

在這里,Promise.resolve(v)靜態方法只是簡單返回一個以v為肯定結果的promise,v可不傳入,也可以是一個函數或者是一個包含then方法的對象或函數(即thenable)。

類似的靜態方法還有Promise.cast(promise),生成一個以promise為肯定結果的promise;

Promise.reject(reason),生成一個以reason為否定結果的promise。

我們實際的使用場景可能很復雜,往往需要多個異步的任務穿插執行,并行或者串行同在。這時候,可以對Promise進行各種擴展,比如實現Promise.all(),接受promises隊列并等待他們完成再繼續,再比如Promise.any(),promises隊列中有任何一個處于完成態時即觸發下一步操作。

標準的Promise

可參考html5rocks的這篇文章JavaScript Promises,目前高級瀏覽器如chrome、firefox都已經內置了Promise對象,提供更多的操作接口,比如Promise.all(),支持傳入一個promises數組,當所有promises都完成時執行then,還有就是更加友好強大的異常捕獲,應對日常的異步編程,應該足夠了。

第三方庫的Promise

現今流行的各大js庫,幾乎都不同程度的實現了Promise,如dojo,jQuery、Zepto、when.js、Q等,只是暴露出來的大都是Deferred對象,以jQuery(Zepto類似)為例,實現上面的getImg():

view sourceprint?01 function getImg(url) {

02 var def = $.Deferred();

03 var img = new Image();

04

05 img.onload = function() {

06 def.resolve(this);

07 };

08

09 img.onerror = function(err) {

10 def.reject(err);

11 };

12

13 img.src = url;

14

15 return def.promise();

16 };

當然,jQuery中,很多的操作都返回的是Deferred或promise,如animate、ajax:

view sourceprint?01 // animate

02 $('.box')

03 .animate({'opacity': 0}, 1000)

04 .promise()

05 .then(function() {

06 console.log('done');

07 });

08

09 // ajax

10 $.ajax(options).then(success, fail);

11 $.ajax(options).done(success).fail(fail);

12

13 // ajax queue

14 $.when($.ajax(options1), $.ajax(options2))

15 .then(function() {

16 console.log('all done.');

17 }, function() {

18 console.error('There something wrong.');

19 });

jQuery還實現了done()和fail()方法,其實都是then方法的shortcut。

處理promises隊列,jQuery實現的是$.when()方法,用法和Promise.all()類似。

其他類庫,這里值得一提的是when.js,本身代碼不多,完整實現Promise,同時支持browser和Node.js,而且提供更加豐富的API,是個不錯的選擇。這里限于篇幅,不再展開。

尾聲

我們看到,不管Promise實現怎么復雜,但是它的用法卻很簡單,組織的代碼很清晰,從此不用再受callback的折磨了。

最后,Promise是如此的優雅!但Promise也只是解決了回調的深層嵌套的問題,真正簡化JavaScript異步編程的還是Generator,在Node.js端,建議考慮Generator。

更多信息請查看IT技術專欄

更多信息請查看網絡編程
易賢網手機網站地址:JavaScript Promise啟示錄
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點

版權所有:易賢網

中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
免费观看91视频大全| 精品国产成人系列| 国产一区在线看| 国产98色在线|日韩| 一本色道久久综合亚洲91| 色美美综合视频| 日韩欧美中文字幕一区| 中文字幕第一区第二区| 亚洲天堂精品在线观看| 亚洲欧美aⅴ...| 老司机精品视频在线| 国产91丝袜在线18| 欧美日韩视频在线一区二区| 日韩欧美在线不卡| 亚洲欧美一区二区久久| 日产精品久久久久久久性色| 国产精品乡下勾搭老头1| 欧美午夜理伦三级在线观看| 久久精品一区二区三区不卡牛牛 | 色狠狠一区二区| 久久中文娱乐网| 亚洲一区二区3| 国产精品亚洲视频| 欧美精品丝袜久久久中文字幕| 久久久九九九九| 秋霞国产午夜精品免费视频| 不卡在线观看av| 精品国精品自拍自在线| 亚洲一二三四在线| www.av精品| 国产女同互慰高潮91漫画| 麻豆精品在线视频| 欧美日韩一区 二区 三区 久久精品| 欧美激情一二三区| 国产一区二区三区精品欧美日韩一区二区三区 | 国产精品成人在线观看| 黑人巨大精品欧美黑白配亚洲| 欧美日韩一区二区三区在线 | 欧美一区二区福利视频| 亚洲成人免费在线观看| 成人激情综合网站| 欧美一级理论片| 老司机精品视频在线| 欧美一区二区三区小说| 秋霞电影网一区二区| 欧美亚洲国产一区在线观看网站| 中文子幕无线码一区tr| 不卡大黄网站免费看| 亚洲国产成人一区二区三区| 不卡的av在线播放| 国产精品第一页第二页第三页| 懂色av中文字幕一区二区三区 | 91精品一区二区三区在线观看| 亚洲国产精品久久一线不卡| 欧美日韩免费电影| 日本成人在线网站| 欧美精品一区二区在线播放| 激情综合网激情| 欧美激情综合五月色丁香| 国产iv一区二区三区| 中文字幕在线一区免费| 在线观看免费亚洲| 日本麻豆一区二区三区视频| 精品毛片乱码1区2区3区| 国产一区二区按摩在线观看| 中文字幕亚洲在| 欧美日韩一级二级三级| 久久精品国产亚洲5555| 国产精品九色蝌蚪自拍| 欧美综合天天夜夜久久| 免费高清在线视频一区·| 久久色视频免费观看| 成人深夜视频在线观看| 亚洲国产乱码最新视频| 欧美草草影院在线视频| 国产成人三级在线观看| 亚洲综合一区在线| 2017欧美狠狠色| 91官网在线免费观看| 黄色日韩网站视频| 亚洲精品视频免费看| 精品久久国产字幕高潮| 91麻豆免费看片| 激情文学综合网| 亚洲图片有声小说| 国产精品欧美极品| 91精品蜜臀在线一区尤物| 成人av网在线| 久久精品国产网站| 亚洲午夜电影网| 国产精品视频麻豆| 91精品国产美女浴室洗澡无遮挡| 国产白丝网站精品污在线入口| 亚洲影视在线播放| 亚洲国产高清在线| 日韩精品资源二区在线| 在线亚洲高清视频| 久久福利资源站| 国产蜜臀97一区二区三区| 欧美一级理论性理论a| 97精品久久久午夜一区二区三区| 日韩av在线播放中文字幕| 自拍偷拍国产亚洲| 国产亚洲自拍一区| 日韩久久久精品| 欧美日韩成人激情| 在线中文字幕一区二区| av成人免费在线| 国产.欧美.日韩| 国产麻豆91精品| 免费看日韩a级影片| 午夜a成v人精品| 亚洲v日本v欧美v久久精品| 亚洲另类中文字| 亚洲丝袜另类动漫二区| 亚洲人成网站精品片在线观看| 国产网红主播福利一区二区| 久久亚洲捆绑美女| 久久久久久久久99精品| 国产亚洲精品福利| 欧美激情综合五月色丁香小说| 久久色.com| 欧美国产乱子伦| 亚洲婷婷综合久久一本伊一区| 中文字幕一区av| 国产精品久久影院| 中文字幕一区在线观看| 亚洲色图清纯唯美| 亚洲女人小视频在线观看| 亚洲黄一区二区三区| 亚洲欧美日韩一区二区| 亚洲一区二区在线免费看| 亚洲成人一区在线| 奇米亚洲午夜久久精品| 国产精品自在在线| youjizz久久| 91免费在线视频观看| 欧美日韩精品欧美日韩精品一| 欧美猛男超大videosgay| 欧美疯狂做受xxxx富婆| 精品播放一区二区| 中文一区二区在线观看| 亚洲一区二区三区在线播放| 亚洲成人免费视| 精品伊人久久久久7777人| 懂色av一区二区三区免费观看 | 精品一区二区在线播放| 粉嫩在线一区二区三区视频| 欧美中文字幕久久| 3atv在线一区二区三区| 日本一区二区三区四区在线视频 | 一区二区三区在线免费播放| 日韩国产高清影视| 国产99久久久国产精品免费看| 色婷婷国产精品久久包臀| 日韩欧美亚洲一区二区| 国产精品久久久久久久午夜片| 亚洲一区在线免费观看| 国产精品一线二线三线精华| 色综合中文字幕| 亚洲精品一区二区三区四区高清| 亚洲欧美日韩久久| 国产综合久久久久久久久久久久| 成人avav在线| 精品国产第一区二区三区观看体验| 中文字幕一区二区三区在线不卡| 五月天欧美精品| 91猫先生在线| 久久人人爽人人爽| 日韩黄色免费网站| 色婷婷久久久综合中文字幕| 国产亚洲人成网站| 五月开心婷婷久久| 99国产精品国产精品毛片| 日韩免费高清av| 成人欧美一区二区三区小说| 久久成人av少妇免费| 欧美精品电影在线播放| 亚洲人成网站精品片在线观看| 韩日av一区二区| 欧美一卡2卡三卡4卡5免费| 亚洲自拍偷拍网站| 91女厕偷拍女厕偷拍高清| 久久嫩草精品久久久久| 精品影院一区二区久久久| 欧美三级电影在线观看| 亚洲三级在线免费观看| 国产成人免费视频| 免费在线观看日韩欧美| 欧美视频一区在线| 一区二区三区欧美久久| 91视频在线看| 国产欧美一区二区在线观看| 久久不见久久见免费视频7| 欧美精品色一区二区三区| 亚洲精品国久久99热| eeuss国产一区二区三区| 国产日本欧美一区二区| 国产精品99久久久久| 精品免费一区二区三区|