摘要:就算改變已經(jīng)發(fā)生了,即使再對對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果。方法接收個參數(shù),第一個參數(shù)是狀態(tài)的回調(diào)函數(shù),第二個參數(shù)可選是狀態(tài)的回調(diào)函數(shù)。簡單來講,就是能把原來的回調(diào)寫法分離出來,在異步操作執(zhí)行完后,用鏈?zhǔn)秸{(diào)用的方式執(zhí)行回調(diào)函數(shù)。
1.許下一個Promise(承諾)在ECMAScript 6標(biāo)準(zhǔn)中,Promise被正式列為規(guī)范,Promise,字面意思就是“許諾,承諾”,嘿,聽著是不是很浪漫的說?我們來探究一下這個浪漫的Promise對象到底是如何許下承諾,又是如何兌現(xiàn)TA的諾言的。
下面我們將通過一些簡單的例子,來一步一步的探究Promise的含義,更重要的是,用心體會Ta的優(yōu)雅和浪漫(PS:讓程序猿體會浪漫,是不是難為大家了)
在ES6標(biāo)準(zhǔn)中被定義為一個構(gòu)造函數(shù),那好我們就先new一個對象出來看看。
var promise = new Promise(function(resolve,reject){ //一個異步操作 setTimeout(function(){ let foo = 1; console.log("執(zhí)行完成"); resolve(foo); }, 2000); });
上面的代碼就可以看作是Promise給我們許下了一個承諾,不過,這特么到底是個啥意思呢?
構(gòu)造函數(shù)Promise接收一個回調(diào)函數(shù)做參數(shù),同時這個回調(diào)函數(shù)又接受2個function做參數(shù),本例中分別起名叫resolve和reject,分別代表異步操作執(zhí)行成功后的操作,和異步操作執(zhí)行失敗后的操作。
ES6標(biāo)準(zhǔn)中規(guī)定一個 Promise的當(dāng)前狀態(tài)必須為以下三種狀態(tài)中的一種:
進(jìn)行中(Pending)
已完成(Resolved 或 Fulfilled)
已失?。?b>Rejected)
下表簡單總結(jié)了三種狀態(tài)所代表的含義:
名稱 | 含義 | 滿足條件 |
---|---|---|
Pending | 進(jìn)行中 | 操作正在執(zhí)行,可以切換為Resolve或Rejected狀態(tài) |
Resolved | 已完成 | 必須擁有一個不可變的終值,且不可以切換到其他狀態(tài) |
Rejected | 已失敗 | 必須擁有一個不可變的終值,且不可以切換到其他狀態(tài) |
當(dāng)Promise的狀態(tài)由pending狀態(tài),通過resolve函數(shù)改變?yōu)?b>resolved,或者通過reject函數(shù)改變?yōu)?b>rejected后,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果。就算改變已經(jīng)發(fā)生了,即使再對Promise對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果。
2.兌現(xiàn)你的承諾最重要的不是看Ta怎么說,重要的是要看Ta怎么做。既然許下了承諾,就必須要兌現(xiàn)承諾。
下面就要介紹Promise.prototype.then()方法,來訪問其當(dāng)前值、終值和據(jù)因。它的作用是為Promise實(shí)例添加狀態(tài)改變時的回調(diào)函數(shù)。then方法接收2個參數(shù),第一個參數(shù)是Resolved狀態(tài)的回調(diào)函數(shù),第二個參數(shù)(可選)是Rejected狀態(tài)的回調(diào)函數(shù)。
廢話不多說直接上示例代碼:
function foo (a){ var promise = new Promise(function(resolve,reject){ setTimeout(function(){ if(a > 0){ resolve(a); }else { reject(a); } }, 2000); }); return promise; } foo(1).then(function(a){ console.log("success",a+1); },function(a){ console.log("error",a); });
上面的代碼中,簡單設(shè)定一個定時任務(wù)模擬異步操作,當(dāng)a>0時,認(rèn)為操作成功,則在then方法中執(zhí)行第一個回調(diào)函數(shù),輸出success;當(dāng)傳入的值 a<0時,就被認(rèn)為操失敗,則then方法執(zhí)行第二個回調(diào)函數(shù),輸出error??吹竭@里,我們可能會感覺到Promise 和我們之前用的回調(diào)函數(shù)有點(diǎn)相似,但是貌似Promise是用同步的寫法來處理異步的操作。簡單來講,Promise就是能把原來的回調(diào)寫法分離出來,在異步操作執(zhí)行完后,用鏈?zhǔn)秸{(diào)用的方式執(zhí)行回調(diào)函數(shù)。
我們了解了以上的基本原理,以后碰到需要傳遞多個callback的情況的時候,就可以使用Promise實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,從而避免陷入回調(diào)地獄中。
示例代碼:
function foo(a) { ++a; console.log(a); var promise = new Promise(function (resolve, reject) { setTimeout(function () { if (a > 0) { resolve(a); } else { reject(a); } }, 2000); }); return promise; } function foo2(a) { ++a; console.log(a); var promise = new Promise(function (resolve, reject) { setTimeout(function () { if (a > 1) { resolve(a); } else { reject(a); } }, 2000); }); return promise; } function foo3(a) { ++a; console.log(a); var promise = new Promise(function (resolve, reject) { setTimeout(function () { if (a > 2) { resolve(a); } else { reject(a); } }, 2000); }); return promise; } function foo4(a) { ++a; console.log(a); var promise = new Promise(function (resolve, reject) { setTimeout(function () { if (a > 3) { resolve(a); } else { reject(a); } }, 2000); }); return promise; } //鏈?zhǔn)秸{(diào)用各個處理函數(shù) foo(1).then(function (a) { return foo2(a); }) .then(function (a) { return foo3(a); }) .then(function (a) { return foo4(a); })3.承諾兌現(xiàn)不了咋辦
并不是所有的承諾都會被兌現(xiàn),就好像小時候父母都說幫我們存壓歲錢以后還給我們一樣。Promise中也是如此,總會有我們意想不到的差錯發(fā)生導(dǎo)致無法按照預(yù)期的函數(shù)進(jìn)行執(zhí)行,
所以Promise提供了一個名為catch的方法幫我們解決這個問題。
Promise.prototype.catch()方法有2個作用,第一個作用,就是和then方法中的第二個參數(shù)作用相同,就是當(dāng)狀態(tài)切換成rejected時執(zhí)行相應(yīng)的操作,例如第一個例子中換個寫法:
foo(1) .then(function(a){ console.log("success",a+1); }) .catch(function(a){ console.log("error",a); });
作用和原來完全一致。
第二個作用就是在執(zhí)行resolve的回調(diào)(也就是上面then中的第一個參數(shù))時,如果拋出異常了(代碼出錯了),那么并不會報(bào)錯卡死js,而是會進(jìn)到這個catch方法中。
要是你在生活中真遇到一個肯為你玩兒命的人。。。。。
關(guān)我毛事,勞資單身狗,秀恩愛的請移步他處。。。。。
Promise中提供了Promise.all方法,注意all方法是直接定義在Promise上的而不是原型鏈中。主要作用就是提供了并行執(zhí)行異步操作的能力,讓程序玩了命的跑起來。
var promise = Promise.all([p1, p2, p3]).then(function (p) { console.log(p); });
Promise.all會將多個Promise的實(shí)例,包裝成一個新的Promise實(shí)例,然后傳遞給后面的then方法。
兼容性Promise.all方法的參數(shù)可以不是數(shù)組,但必須具有Iterator接口,且返回的每個成員都是Promise實(shí)例
說了這么多,哇塞這么優(yōu)雅的特性一定要用起來啊,但是在激動之余,畢竟Promise是ES6標(biāo)準(zhǔn)中的新增對象,所以還是得冷靜下來檢查一下Promise對象的兼容性如何,
通過在can I use...網(wǎng)站上獲取到的統(tǒng)計(jì)數(shù)據(jù)看來,Promise對象的兼容性不是很好,目前只有在比較新的主流瀏覽器中才得到全面支持,而且我們注意到微軟的所有IE瀏覽器均不支持該對象,只有在win10中的Edge瀏覽器中才獲得支持??磥砦覀冊跍?zhǔn)備使用Promise的時候,還是要視自己的實(shí)際開發(fā)環(huán)境而定。
總結(jié)關(guān)于ES6的其他特性的最新支持情況,請點(diǎn)擊這里
Promise作為ES6標(biāo)準(zhǔn)中一個比較新鮮的特性,還有其他方法這里沒有講到,比如resolve,reject,race等,受限于水平與時間精力,今天暫時先寫這么多,以后有時間再繼續(xù)補(bǔ)充,對于文中的錯誤和不足,歡迎大家指出討論,共同學(xué)習(xí)進(jìn)步(雖然我不一定看。。。。逃。。)
附:在GitHub上閱讀請點(diǎn)擊
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80784.html
摘要:使用時也要注意范圍和層級。服務(wù)端配置服務(wù)端使用,最簡單的方式是通過。云引擎是推出的服務(wù)器端運(yùn)行環(huán)境,支持和環(huán)境,功能強(qiáng)大而且目前免費(fèi),結(jié)合,使原本復(fù)雜的開發(fā)工作變得簡單高效。目前也支持和海外節(jié)點(diǎn),輕松滿足你的業(yè)務(wù)需求。 構(gòu)建一個應(yīng)用程序總是會面對異步調(diào)用,不論是在 Web 前端界面,還是 Node.js 服務(wù)端都是如此,JavaScript 里面處理異步調(diào)用一直是非常惡心的一件事情。以...
摘要:故而總結(jié)如下編成的代碼浪漫的環(huán)境親手制作的禮物注意請將下面的程序員的情人節(jié)禮物換成語言。言歸正傳程序員的情人節(jié)禮物入門之材料構(gòu)思情人節(jié)禮物之設(shè)備展示想著在這個移動盛行的時代,再用電腦就不太合適了。 是時候應(yīng)該反擊了 當(dāng)我看到@鄢得諼草 的那幾篇黑我黑到體無完膚的#極客愛情# @Phodal 故事的時候,我發(fā)現(xiàn)我竟無言以對?;蛟S,作為一名程序員,我們或多或少都有這樣的共性。 ...
摘要:周五就想寫這篇文章,但是無奈花花世界的誘惑太多就一直拖到了今天,自責(zé)遍進(jìn)入正題對象用于表示一個異步操作的最終狀態(tài)完成或失敗,以及其返回的值。 周五就想寫這篇文章,但是無奈花花世界的誘惑太多……就一直拖到了今天,自責(zé)1e4遍;進(jìn)入正題Promise: Promise 對象用于表示一個異步操作的最終狀態(tài)(完成或失?。?,以及其返回的值。 上為MDNPromise的定義;ES6規(guī)定Promis...
摘要:標(biāo)準(zhǔn)引入了函數(shù),使得異步操作變得更加方便。在異步處理上,函數(shù)就是函數(shù)的語法糖。在實(shí)際項(xiàng)目中,錯誤處理邏輯可能會很復(fù)雜,這會導(dǎo)致冗余的代碼。的出現(xiàn)使得就可以捕獲同步和異步的錯誤。如果有錯誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,請?wù)必給予指正,十分感謝。 async ES2017 標(biāo)準(zhǔn)引入了 async 函數(shù),使得異步操作變得更加方便。 在異步處理上,async 函數(shù)就是 Generator 函數(shù)的語法糖。 ...
摘要:今天我們接著上次的內(nèi)容繼續(xù)扯,如何實(shí)現(xiàn)數(shù)據(jù)傳遞以及當(dāng)回調(diào)函數(shù)返回一個新的上篇已完成的代碼測試代碼上面的結(jié)果,就是我們要實(shí)現(xiàn)的。然后,等到下次需要的時候,再傳給下一個回調(diào)函數(shù)。先來修改方法,因?yàn)榛卣{(diào)函數(shù)都是在這里運(yùn)行的。 上一篇文章【實(shí)現(xiàn)簡易 ES6 Promise 功能 (一)】實(shí)現(xiàn)了基本的異步功能。今天我們接著上次的內(nèi)容繼續(xù)扯,如何實(shí)現(xiàn)【數(shù)據(jù)傳遞】以及當(dāng)【回調(diào)函數(shù)返回一個新的prom...
閱讀 1853·2023-04-26 02:14
閱讀 3774·2021-11-23 09:51
閱讀 1420·2021-10-13 09:39
閱讀 4003·2021-09-24 10:36
閱讀 3037·2021-09-22 15:55
閱讀 3542·2019-08-30 12:57
閱讀 2060·2019-08-29 15:30
閱讀 2011·2019-08-29 13:19