這篇文章說說我對promise的理解。
盤山網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,盤山網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為盤山超過千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務(wù)好的盤山做網(wǎng)站的公司定做!
promise在ES6之前就有的寫法,在ES6中寫入了語言標(biāo)準(zhǔn),于是就有了原生promise對象。
promise對象能更好的改善異步操作的回調(diào)地獄,把多層嵌套扁平化,看上去像同步執(zhí)行的代碼,更容易閱讀和理解。由于js語法的靈活多變,也導(dǎo)致了promise的寫法多樣。
promise有三種狀態(tài)來表示當(dāng)前執(zhí)行的進(jìn)度,pending,resolve,reject。promise執(zhí)行后,默認(rèn)是pending狀態(tài),意思是正在執(zhí)行,promise有兩種狀態(tài)變化,并且是不可逆的,第一種就是從pending到resolve,從正在執(zhí)行到執(zhí)行成功,第二種是pending到reject,從執(zhí)行中到執(zhí)行失敗。
promise一旦開始執(zhí)行,就不能停止,直到執(zhí)行結(jié)束。
如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反應(yīng)到外部。
當(dāng)處于Pending狀態(tài)時,無法得知目前進(jìn)展到哪一個階段(剛剛開始還是即將完成)。下面我就針對promise的常規(guī)用法,鏈?zhǔn)秸{(diào)用,all方法,race方法這四方面來說說我對promise的理解。
先說常規(guī)用法:
let promise = new Promise(function (resolve,reject){ let res = 1+2+3; if(res>1){ resolve(res); }else{ reject("err"); } }); //結(jié)果接收方式1 promise.then(function (res){ console.log(res); },function (err){ console.log(err); }); //結(jié)果接收方式2 promise.then(function (res){ console.log(res); }).catch(function (err){ console.log(err); }); //結(jié)果接收方式3 promise.then(function (res){ console.log(res); }); promise.catch(function (err){ console.log(err); });
常規(guī)用法就是聲明一個promise對象,寫入邏輯,根據(jù)邏輯的返回結(jié)果確定是執(zhí)行成功還是執(zhí)行失敗,執(zhí)行成功就調(diào)用resolve方法,該方法接受一個參數(shù),可以把邏輯返回的結(jié)果傳到外面來使用。執(zhí)行失敗可以調(diào)用reject方法,該方法也可以傳數(shù)據(jù)到外部,一般是傳錯誤信息。
在上面的代碼中我寫了三種結(jié)果接收方式,先說第一種:
//結(jié)果接收方式1 promise.then(function (res){ console.log(res); },function (err){ console.log(err); });
promise有then方法,可以傳兩個參數(shù),兩個參數(shù)都是function,用來接收數(shù)據(jù),第一個參數(shù)是接收邏輯執(zhí)行成功的返回值,第二個參數(shù)接收邏輯執(zhí)行失敗的返回值。當(dāng)然這種看上去也會有一些嵌套的感覺,我一般是不用這種寫法的。
//結(jié)果接收方式2 promise.then(function (res){ console.log(res); }).catch(function (err){ console.log(err); });
我的個人理解是promise提供了then方法,又提供了catch方法,就是為了分別接收不同的邏輯執(zhí)行結(jié)果的,then方法就是為了接收成功返回的結(jié)果,那相應(yīng)的,catch方法就是為了接收失敗返回的結(jié)果,node.js中鏈?zhǔn)秸{(diào)用很常見,這種寫法也是一種鏈?zhǔn)秸{(diào)用,我是比較喜歡這種用法的。
//結(jié)果接收方式3 promise.then(function (res){ console.log(res); }); promise.catch(function (err){ console.log(err); });
當(dāng)然,既然promise提供了then和catch兩個方法接收結(jié)果,自然也可以用方法3來接收邏輯返回的結(jié)果,有些童鞋喜歡看起來很明朗的代碼風(fēng)格,那就是這種了,這種只是比第二種方式多了(promise對象.)這么一點(diǎn)代碼。其實(shí)看起來是挺工整的。
下面再說說promise的鏈?zhǔn)秸{(diào)用:
假設(shè)一種情況:你在A文件里記錄的B文件的名字,在B文件里記錄的C的名字,又在C文件里記錄的D文件的名字,你現(xiàn)在知道A文件的名字,想得到D文件的內(nèi)容,該怎么來寫呢?我會這樣寫:
new Promise(function(resolve,reject){ let res1 = 1;//res1邏輯 if(res1){ console.log("res1",res1); resolve(res1); }else{ reject('new Error1()'); } }).then(function (res){ return new Promise(function (resolve,reject){ let res2 = 2+res;//res2邏輯 if(res2){ console.log("res2",res2); resolve(res2); }else{ reject("new Error2"); } }); }).then(function (res){ return new Promise(function (resolve,reject){ let res3 = 3 + res;//res3邏輯 if(res3){ console.log("res3",res3); resolve(res3); }else{ reject('new Error3'); } }); }).then(function (res){ console.log("res",res);//res3結(jié)果 } );
先在res1邏輯中用A文件的名字讀取A文件的內(nèi)容,得到的結(jié)果resolve出去。在then中接收。
然后在res2邏輯中取得A文件內(nèi)容,解析出B文件名字,再讀取B文件內(nèi)容,resolve出去。在then中接收,一直到res3結(jié)果這里得到D文件的內(nèi)容,如果是用回調(diào)函數(shù)的話估計(jì)就要嵌套很多層了,而用promise,就能很直觀的看清代碼走勢,是不是很簡單,當(dāng)然這一段代碼我一直覺得應(yīng)該有更簡潔的寫法,但無奈本領(lǐng)不到家,只能寫成這樣了,如果有大神看見的話,請賜教。
這一段就是promise的鏈?zhǔn)秸{(diào)用,寫個簡潔的就是
new Promise().then().then().then();
好吧,下面說說promise的all方法:
function test(value){ let promise = new Promise(function (resolve,reject){ value = value * 2; if(value){ resolve(value); }else{ reject("err"+value); } }); return promise; } let promArr = [1,2,3,4,5,6,7,8,9,10].map(function (i){ return test(i); }); Promise.all(promArr).then(function (posts){ console.log(posts); }).catch(function (err){ console.log(err); });
這里假設(shè)我需要執(zhí)行10個異步操作,并把他們的結(jié)果放到一個數(shù)組里同時傳給一個方法,那all方法就能派上用場了,在這里需要重點(diǎn)說明一下:如果10個promise都是返回成功的話,也就是promise內(nèi)部邏輯都是調(diào)用了resolve(value)方法的話,promise.then才能接收到最終的10個promise的結(jié)果組成的數(shù)組,就是上面代碼中的posts,假如其中一個promise執(zhí)行失敗,那么,不好意思,你就只能在catch中收到這個失敗的promise返回的錯誤信息了,是的,只能收到執(zhí)行失敗的promise返回的錯誤信息,這就是all方法。大概可以理解成這樣:
let a = true && true && true && true;
當(dāng)所有的表達(dá)式都為true時a才能等于true,有一個表達(dá)式為false時,a就不能等于true;
下面再說一下race方法。這個方法有點(diǎn)奇特,舉個例子,一個孕婦懷了四胞胎,那誰是老大呢,當(dāng)然是先出生的是老大了,而race方法最奇特的地方就在于我只想知道老大是誰,不管后面誰是老二老三,或者說race是一個非常狠心的父親,只想要老大這一個孩子,后面的小孩一個也不要,就算出生了也是扔在醫(yī)院不管不問??创a:
function test(value){ let promise = new Promise(function (resolve,reject){ setTimeout(function (){ resolve(value); },Math.random() * 10000); }); return promise; } let promArr = [1,2,3,4,5,6,7,8,9,10].map(function (i){ return test(i); }); Promise.race(promArr).then(function (post){ console.log('post',post); }).catch(function (err){ console.log('err',err); }).finally(function (){ console.log('finally'); });
這個例子的意思是有10個promise,每個的邏輯都是延時一段時間,時間隨機(jī),誰先執(zhí)行完誰就先返回。
最后的結(jié)果是post只能得到一個值,但別的延時還沒執(zhí)行完之前,這段程序不會結(jié)束,那也就意味著其他9個promise仍然會執(zhí)行到底,但我們是獲取不到他們9個的結(jié)果的,只能得到第一個返回的promise的結(jié)果。
恩。就先暫時說這么多吧,promise還有一個done方法和finally方法,done方法是放在then鏈最后,是用來捕獲中間發(fā)生的任何異常的,這個沒有試驗(yàn),finally據(jù)說是不論then和catch執(zhí)行了哪一個都會執(zhí)行finally方法,但我試驗(yàn)了卻報錯了,有興趣的同學(xué)可以研究一下。
網(wǎng)站名稱:node.js學(xué)習(xí)筆記之promise
文章位置:http://chinadenli.net/article48/jsiohp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、云服務(wù)器、建站公司、服務(wù)器托管、、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)