摘要:入門之基本用法背景在我們使用異步函數(shù)比如進(jìn)行編寫代碼,如果我們需要很多個(gè)請(qǐng)求不同的接口,而下一個(gè)接口需要依賴上一個(gè)接口的返回值,這樣,我們的代碼則需要在各種回調(diào)函數(shù)中嵌套,這樣一層一層地下去,就形成了回調(diào)地獄。
Promise入門之基本用法 背景
在我們使用異步函數(shù)比如ajax進(jìn)行編寫代碼,如果我們需要很多個(gè)ajax請(qǐng)求不同的接口,而下一個(gè)接口需要依賴上一個(gè)接口的返回值,這樣,我們的代碼則需要在各種回調(diào)函數(shù)中嵌套,這樣一層一層地下去,就形成了回調(diào)地獄。
但是promise的出現(xiàn)則不需要嵌套就能解決這個(gè)問題。什么是promise?promise本質(zhì)其實(shí)是一個(gè)對(duì)象,用于傳遞異步操作的信息。并且promise這個(gè)對(duì)象提供了相對(duì)應(yīng)的API,滿足我們的需求開發(fā)。
let pro = new Promise(function(resolve, reject){ // 異步處理邏輯 // 處理完畢之后調(diào)用resolve或者reject })
promise對(duì)象跟其他普通對(duì)象的創(chuàng)建方法一樣,只需要new一個(gè)新的對(duì)象即可,接受一個(gè)函數(shù)作為參數(shù),并且該函數(shù)中的參數(shù)分別為兩個(gè)回調(diào)函數(shù),用于進(jìn)行不同的邏輯處理。
在定完一個(gè)promise對(duì)象之后,我們可以通過調(diào)用then方法來執(zhí)行其對(duì)應(yīng)的邏輯
pro.then(function(res){ // 如果promise對(duì)象調(diào)用了resolve方法,則進(jìn)入該函數(shù)邏輯 }, function(err){ // 如果promise對(duì)象調(diào)用了reject方法,則進(jìn)入該函數(shù)邏輯 })promise的狀態(tài)
promise的實(shí)例主要有以下三種狀態(tài):
①pending: 處理中
②fulfilled: 成功
③rejected: 失敗
pending狀態(tài)的promise可以轉(zhuǎn)化為fulfilled狀態(tài)或者rejected狀態(tài),該轉(zhuǎn)化不可逆且只能轉(zhuǎn)化一次。同時(shí),fulfilled狀態(tài)和rejected狀態(tài)只能由pending狀態(tài)轉(zhuǎn)化,相互不能轉(zhuǎn)化。如圖
pending狀態(tài)下的promise在處理完業(yè)務(wù)邏輯,且能正常退出時(shí)便可以執(zhí)行resolve方法,從而進(jìn)入fulfilled狀態(tài);
若pending狀態(tài)下的promise在處理業(yè)務(wù)邏輯的過程中出現(xiàn)異常錯(cuò)誤,或者主動(dòng)調(diào)用reject方法,則進(jìn)入rejected狀態(tài)。
let pro = new Promise(function(resolve, reject){ if(// 邏輯處理完畢且能正常退出){ resolve() } else{ // 異常錯(cuò)誤拋出 reject() } }) pro.then(function(res){ // 如果promise對(duì)象調(diào)用了resolve方法,則進(jìn)入該函數(shù)邏輯 }, function(err){ // 如果promise對(duì)象調(diào)用了reject方法,則進(jìn)入該函數(shù)邏輯 })鏈?zhǔn)秸{(diào)用
因?yàn)閜romise對(duì)象中的then方法的返回值是一個(gè)新的promise對(duì)象,因此可以實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用。但后一個(gè)then方法的執(zhí)行必須等待前一個(gè)then方法返回的promise對(duì)象狀態(tài)轉(zhuǎn)為fulfilled或者rejected,若promise對(duì)象處于pending狀態(tài)下,則后一個(gè)then方法只能等待。
pro.then(function(res){ // 第一個(gè)promise對(duì)象邏輯執(zhí)行 return newPro;// 返回一個(gè)新promise }).then(function(res){ // 對(duì)newPro這個(gè)對(duì)象進(jìn)行處理 }) // ...可以一直鏈?zhǔn)秸{(diào)用下去異常捕捉
promise中的catch方法其實(shí)就是pro.then(null, rejection),用戶捕捉代碼運(yùn)行中的錯(cuò)誤異常。
pro.then(function(res){ // 邏輯處理,但存在異常 }).catch(function(err){ // 捕捉上一個(gè)then函數(shù)中所出現(xiàn)的異常錯(cuò)誤 })
此外,catch方法的所捕捉的異常不僅僅局限于上一個(gè)then方法內(nèi),而是可以把錯(cuò)誤一直傳遞下來,直至遇到的第一個(gè)catch,然后被捕捉。如鏈?zhǔn)秸{(diào)用中:
pro.then(function(res){ // 邏輯處理,但存在異常 }).then({ // 邏輯處理 }).catch(function(err){ // 捕捉上面第一個(gè)出現(xiàn)異常的then函數(shù)中所出現(xiàn)的錯(cuò)誤 })promise.all
promise.all方法可以接受一個(gè)由promise組成的數(shù)組作為參數(shù),包裝成一個(gè)新的promise對(duì)象,并且按照數(shù)組中promise的順序進(jìn)行異步執(zhí)行。如:
let pro1 = new Promise(function(resolve, reject){}); let pro2 = new Promise(function(resolve, reject){}); let pro3 = new Promise(function(resolve, reject){}); let proAll = promise.all([pro1, pro2, pro3]);
proAll的狀態(tài)由pro1,pro2,pro3三者共同決定:
①pending: 處理中,pro1,pro2,pro3中無rejected且存在pending狀態(tài)。
②rejected: pro1,pro2,pro3中存在一個(gè)rejected。
③fulfilled:pro1,pro2,pro3三者均為fulfilled。
當(dāng)proAll的狀態(tài)為fulfilled時(shí),會(huì)返回一個(gè)數(shù)組,該數(shù)組中的元素則是上面由promise組成的數(shù)組相對(duì)應(yīng)執(zhí)行后的結(jié)果。
promise.racepromise.race所接受的參數(shù)與promise.all一致,但promise.race的返回值則是由pro1,pro2,pro3三者中最先完成的promise對(duì)象決定,并且返回值為該最早完成的promise對(duì)象的返回值。
let proAll = promise.race([pro1, pro2, pro3]);promise.resolve
promise.resolve方法能將一個(gè)對(duì)象轉(zhuǎn)換成promise對(duì)象
let newPro = promise.resolve(obj);
①若obj不具有then方法,則newPro直接變?yōu)閒ulfilled狀態(tài)
let newPro = promise.resolve("i am not a promise"); newPro.then(function(str){ console.log(str) // 輸出 i am not a promise })
②如果obj本就是一個(gè)Promise對(duì)象,則promise.resolve會(huì)將obj直接返回。
promise.rejectpromise.reject方法與promise.resolve一樣,能將一個(gè)對(duì)象轉(zhuǎn)換成promise對(duì)象,但返回的promise對(duì)象的狀態(tài)為rejected。
async/awaitasync是關(guān)鍵詞,在一個(gè)函數(shù)名之前加上該關(guān)鍵詞,表明該函數(shù)內(nèi)部有異步操作,而這異步操作應(yīng)該返回一個(gè)promise對(duì)象,并且在這異步操作之前添加await關(guān)鍵詞。當(dāng)函數(shù)執(zhí)行的時(shí)候,遇到await則會(huì)先進(jìn)行Promise的邏輯處理,帶promise的狀態(tài)不再為pending時(shí)再執(zhí)行該函數(shù)后面的語句。
let pro = new Promise(function(resolve, reject){ // 異步處理邏輯 resolve(); }) async function asyncFunc(){ // 正常執(zhí)行的語句 await pro; // 等待promise處理完之后再執(zhí)行的語句 } asyncFunc();總結(jié)
promise的出現(xiàn),為我們編寫異步函數(shù)定下不少規(guī)則,在優(yōu)化我們代碼的同時(shí)也能減少代碼量,并增強(qiáng)可讀性,但也需嚴(yán)格遵守promise/A+的規(guī)范進(jìn)行promise的開發(fā)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103095.html
摘要:是異步編程的另一種解決方案函數(shù)是對(duì)函數(shù)的改進(jìn)的基本用法函數(shù)函數(shù)返回一個(gè)實(shí)例,可以使用方法為返回的實(shí)例添加回調(diào)函數(shù)。函數(shù)內(nèi)部語句返回的值,會(huì)成為方法回調(diào)函數(shù)的參數(shù)。也就是說,只有函數(shù)內(nèi)部的異步操作執(zhí)行完,才會(huì)執(zhí)行方法指定的回調(diào)函數(shù)。 async await async await是異步編程的另一種解決方案 async函數(shù)是對(duì)Generator函數(shù)的改進(jìn) async的基本用法 asyn...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
摘要:現(xiàn)在我們要用的重點(diǎn)就是我們的,這是一個(gè)能讓函數(shù)并行的,可以基于多個(gè)。非常有用啊先上一個(gè)錯(cuò)誤的代碼這時(shí)候我們得到的就是數(shù)字了,而不是一個(gè)數(shù)組,這就是神奇所在。 看過 (一)的同學(xué)一定覺得這個(gè)Promise很簡單,好像沒什么可以用的地方,但是事實(shí)上,它的用處非常大啊,尤其是在nodejs上,愈加重要,雖然已經(jīng)有大量的庫實(shí)現(xiàn)了對(duì)Promise的封裝了,不過我還是更傾向用原生的node來實(shí)現(xiàn)對(duì)...
閱讀 2774·2021-09-24 10:34
閱讀 1876·2021-09-22 10:02
閱讀 2265·2021-09-09 09:33
閱讀 1469·2021-08-13 15:02
閱讀 3279·2020-12-03 17:10
閱讀 1193·2019-08-30 15:44
閱讀 2156·2019-08-30 12:58
閱讀 3237·2019-08-26 13:40