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