一文帶你了解promise并解決回調(diào)地獄
Promise
為什么需要promise
需求
通過ajax請求id,再根據(jù)id請求用戶名,再根據(jù)用戶名獲取email
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./jquery-3.6.0.js"></script> </head> <body> <script> //通過ajax請求拿到用戶id $.ajax({ type:"GET", url:"./data1.json", success:function(res){ let {id} = res; console.log(id); //通過用戶id找到用戶名 $.ajax({ type:"get", url:'./data2.json', data:{id}, success:function(res){ let {username} = res; console.log(username); //通過用戶名找到用戶郵箱 $.ajax({ type:"GET", url:"./data3.json", data:{username}, success:function(res){ let {email} = res; console.log(email); } }) } }) } }) </script> </body> </html>
回調(diào)地獄
在回調(diào)函數(shù)中嵌套回調(diào)
在上述代碼中通過不斷請求數(shù)據(jù),代碼逐級向外遞歸,形成了回調(diào)地獄。
使用promise就可以完美解決,并且讓我們的代碼更加美觀。
Promise的基本使用
Promise是一個構(gòu)造函數(shù),通過new關(guān)鍵字實例化對象.
語法:
new promise((reso1ve,reject)=>{})
Promise接受一個函數(shù)作為參數(shù)
在參數(shù)函數(shù)中接受兩個參數(shù)
- resolve:
- reject:
promise實例
promise實例有兩個屬性:
- state:狀態(tài)
- result:結(jié)果
promise的狀態(tài)
- pending(準備,待解決,進行中)
- fulfilled(已完成,成功)
- rejected(已拒絕,失敗)
promise狀態(tài)的改變
通過調(diào)用resolve和reject改變當前promise對象的狀態(tài)。
- 改為fulfilled
let p = new Promise((resolve,reject)=>{ resolve(); //調(diào)用resolve將狀態(tài)改為fulfilled }); console.log(p)
- 改為rejected
let p = new Promise((resolve,reject)=>{ reject();//調(diào)用reject將狀態(tài)改為rejected }); console.log(p)
注意:promise狀態(tài)的改變是一次性的,即不能同時調(diào)用resolve和reject,若同時調(diào)用則狀態(tài)只改變一次。
promise的結(jié)果
promise的結(jié)果是通過傳遞resolve/reject的參數(shù)來獲得的
let p = new Promise((resolve,reject)=>{ resolve("成功") }) console.log(p);
同理,reject也是如此:
promise方法
then方法
then方法中有兩個參數(shù),且都為函數(shù)作為參數(shù)。
如:
let p = new Promise((resolve,reject)=>{ resolve("成功") }) p.then(()=>{ console.log('成功時執(zhí)行'); },()=>{ console.log("失敗時執(zhí)行"); }) console.log(p);
- 第一個函數(shù)參數(shù)
當promise的狀態(tài)為fulfilled時,執(zhí)行該函數(shù) - 第二個函數(shù)參數(shù)
當promise的狀態(tài)為rejected時,執(zhí)行該函數(shù)
通過then方法獲取promise的結(jié)果
通過then方法中的函數(shù)傳遞形參即可獲得promise的結(jié)果;
let p = new Promise((resolve,reject)=>{ resolve("成功") }) p.then((value)=>{ console.log('成功時執(zhí)行',value); },(reason)=>{ console.log("失敗時執(zhí)行",reason); }) console.log(p);
總結(jié):promise的狀態(tài)用來判斷then方法執(zhí)行成功或是失敗的函數(shù),promise的結(jié)果則是作為實參傳遞給then方法的函數(shù)參數(shù)的形參。
then方法的返回值
then方法返回的為一個新的promise對象。且該promise對象的狀態(tài)為pending,then方法為一個同步操作,then中的函數(shù)參數(shù)為異步操作。
如上圖我們就可以看到then方法的返回值仍然為一個promise對象,且在剛生成該對象時的狀態(tài)為pending。
由此衍生出了鏈式操作:
new Promise(()=>{}).then().then()
在該操作中,如果promise對象的狀態(tài)不改變則不會執(zhí)行then方法中的函數(shù)。那么在then方法返回的promise對象中如何讓其狀態(tài)改變呢??
- 使用return可以將then方法返回的promise對象狀態(tài)改為fulfilled。
- 在then方法中書寫錯誤代碼,即可將其promise對象狀態(tài)改為rejected
實例:
let p = new Promise((res,rej)=>{ res('蘇涼'); }) let t = p.then((value)=>{ return "name:"+value; },(reason)=>{ console.log("執(zhí)行失??!"); }) t.then((value)=>{ console.log(value); },(reason)=>{ console.log(reason); }) console.log(t);
catch方法
catch方法在promise對象的狀態(tài)為rejected時亦或者是輸入錯誤代碼時被調(diào)用,并返回錯誤原因。
let p = new Promise((res,rej)=>{ throw newError("出錯啦!") }) p.catch((reason)=>{ console.log(reason); }) console.log(p);
解決回調(diào)地獄
//封裝Ajax請求函數(shù) function getAjax(path,data){ return new Promise((resolve,reject)=>{ $.ajax({ type:'get', url:path, data:{data}, success:function(res){ resolve(res) }, error:function(res){ reject(res) } }) }) } getAjax('./data1.json') .then((value)=>{ let id = {value}; return getAjax("./data2.json",id) }) .then((value)=>{ let {username} = value; return getAjax('./data3.json',username) }) .then((value)=>{ console.log(value); })
以上就是一文帶你了解promise并解決回調(diào)地獄的詳細內(nèi)容,更多關(guān)于promise回調(diào)地獄的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序教程系列之頁面跳轉(zhuǎn)和參數(shù)傳遞(6)
這篇文章主要為大家詳細介紹了微信小程序教程系列之頁面跳轉(zhuǎn)和參數(shù)傳遞,微信小程序提供了3種頁面跳轉(zhuǎn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04網(wǎng)頁中右鍵功能的實現(xiàn)方法之contextMenu的使用
本文介紹一種網(wǎng)頁中實現(xiàn)右鍵功能的方案–contextMenu,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02JS獲取鼠標坐標并且根據(jù)鼠標位置不同彈出不同內(nèi)容
這篇文章主要介紹了js獲取鼠標坐標并且根據(jù)鼠標位置不同彈出不同內(nèi)容的實例代碼,需要的朋友可以參考下2017-06-06javascript數(shù)組常見操作方法實例總結(jié)【連接、添加、刪除、去重、排序等】
這篇文章主要介紹了javascript數(shù)組常見操作方法,結(jié)合實例形式總結(jié)分析了javascript數(shù)組的連接、添加、刪除、去重、排序等操作,代碼注釋附帶較為詳細的說明,需要的朋友可以參考下2019-06-06JavaScript 處理Iframe自適應(yīng)高度(同或不同域名下)
Iframe自適應(yīng)高度一直都備受關(guān)注,接下來為大家介紹下同域名下Iframe自適應(yīng)高度的處理以及跨域時Iframe高度自適應(yīng),感興趣的朋友可以參考下哈2013-03-03微信小程序中做用戶登錄與登錄態(tài)維護的實現(xiàn)詳解
微信小程序的運行環(huán)境不是在瀏覽器下運行的。所以不能以cookie來維護登錄態(tài)。下面這篇文章主要給大家介紹了微信小程序中如何做用戶登錄與登錄態(tài)維護的相關(guān)資料,文中介紹的非常詳細,需要的朋友可以參考學習。2017-05-05