Promise
1.Promise基本介紹
Promise是異步編程的一種解決方案,可以解決傳統Ajax回呼函式嵌套問題,
- 傳統的Ajax異步呼叫在需要多個操作的時候,會導致多個回呼函式嵌套,導致代碼不夠直觀,就是常說的Callback Hell
- 為了解決上述的問題,Promise物件應運而生,在EMCAScript 2015當中已經成為標準,Promise也是ES6的新特性
- Promise是異步編程的一種解決方案
- 從語法上說,Promise是一個物件,從它可以獲取異步操作的訊息
2.Promise應用實體
2.1需求分析/圖解
-
需求:演示promise異步請求使用
-
執行效果:
2.2代碼實作
使用json檔案模擬資料庫表資料
monster.json
{
"id": 1,
"name": "黑山老妖"
}
monster_detail_1.json
{
"id": 1,
"address": "黑山洞",
"skill": "翻江倒海",
"age": 500,
"gfid": 2
}
monster_gf_2.json
{
"name": "狐貍精",
"age": 100
}
2.2.1jquery-ajax實作多次ajax請求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jquery-ajax多次請求</title>
<!--引入jquery-->
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/p/script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
//jquery發出ajax的方式
$.ajax({
url: "data/monster.json",
success(resultData) {//第一次ajax成功的回呼函式
console.log("第一次ajax請求 monster 基本資訊=", resultData);
//發出第二次ajax請求
$.ajax({
//第二次ajax請求的url根據第一次的結果來改變
url: `data/monster_detail_${resultData.id}.json`,
success(resultData) {//第二次ajax成功的回呼函式
console.log("第二次ajax請求 monster 詳細資訊=", resultData);
},
error(err) {
console.log("第二次ajax請求出現例外=", err);
}
})
},
error(err) {
console.log("第一次ajax請求出現例外=", err);
}
})
</script>
</head>
<body>
</body>
</html>
使用jquery-ajax的方式容易出現回呼函式嵌套(Callback Hell),如果發出的是多次ajax請求,那么嵌套的層數將會變得非常多,代碼不易讀,這種寫法冗余度高,代碼可維護性低,
2.2.2promise物件實作多次ajax請求
首先創建一個Promise物件,在該物件內傳入一個箭頭函式,箭頭函式內進行ajax請求,Promise物件的箭頭函式傳入了兩個方法作為引數(命名隨意),這里的resolve方法是ajax請求成功后呼叫的函式,reject方法是ajax請求失敗后呼叫的函式,不同于jquery的回呼嵌套,在ajax請求成功的success方法中會呼叫resolve(),并且把第一次ajax請求獲得的資料傳入該方法,
resolve方法會跳到Promise物件的then()方法,then方法中可以繼續使用$.ajax()去進行第二次ajax請求,在then方法中,又創建了一個Promise物件,該物件和之前的Promise物件中的業務邏輯相似,不同的是可以通過上一次的resolve方法,拿到第一次ajax請求回傳的資料,然后根據資料進行第二次的ajax請求.......在第二次的ajax請求中,又可以獲取第二次ajax請求回傳的資料,然后呼叫這次Promise物件的resolve(),將新的資料傳給這次Promise物件的then()方法.....
即,第二次ajax請求的resolve方法又會跳到Promise物件的then()方法........以此類推,
整個程序形成了一個鏈式的呼叫,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用promise完成多次ajax請求</title>
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/p/script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
//先請求到monster.json
//1.創建Promise物件
//2.建構式需要傳入一個箭頭函式
//3.(resolve, reject)引數串列,resolve:如果請求成功,呼叫resolve函式
// reject:如果請求失敗,呼叫reject函式
//4.箭頭函式體內仍然是通過jquery發出ajax
let promise = new Promise((resolve, reject) => {
//發出ajax請求
$.ajax({
url: "data/monster.json",
success(resultData) {//第一次ajax請求成功的回呼函式
console.log("Promise發出的第一次ajax請求,回傳的monster基本資訊=", resultData);
resolve(resultData);
},
error(err) {
//console.log("Promise第一次異步請求出現例外=", err);
reject(err);
}
})
});
//這里我們可以繼續撰寫第一次請求成功之后的業務
//仍然使用箭頭函式
promise.then((resultData) => {
//這里可以繼續發出請求
return new Promise((resolve, reject) => {
$.ajax({
url: `data/monster_detail_${resultData.id}.json`,
success(resultData) {//第二次ajax請求成功的回呼函式
console.log("Promise發出的第二次ajax請求,回傳的monster詳細資訊=", resultData);
//可以繼續進行下一次的請求
resolve(resultData);
},
error(err) {
//console.log("Promise第二次異步請求出現例外=", err);
reject(err);
}
})
})
}).then((resultData) => {
console.log("promise.then().then(),resultDate", resultData);
//這里可以繼續發出第三次ajax請求....
return new Promise(((resolve, reject) => {
$.ajax({
url: `data/monster_gf_${resultData.gfid}.json`,
success(resultData) {//第二次ajax請求成功的回呼函式
console.log("Promise發出的第三次ajax請求,回傳的monster gf資訊=", resultData);
//可以繼續進行下一次的請求
//resolve(resultDate);
},
error(err) {
//console.log("Promise第三次次異步請求出現例外=", err);
reject(err);
}
})
}))
}).catch((err) => {//這里可以對多次ajax請求的例外進行處理
console.log("promise異步請求例外=", err);
})
</script>
</head>
<body>
</body>
</html>
2.2.3promise代碼重排
雖然在2.2.2中使用promise實作了多次ajax請求,解決了jquery-ajax的嵌套回呼問題,但是代碼仍然顯得臃腫,創建Promise物件和進行ajax請求的代碼是重復的,因此可以進行封裝,代碼重排,增強可讀性,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>promise代碼重排</title>
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/p/script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
/**
* 這里我們將重復的代碼封裝,撰寫為get方法
* @param url ajax請求的資源
* @param data ajax請求攜帶的資料
* @returns {Promise<unknown>}
*/
function get(url, data) {
return new Promise(((resolve, reject) => {
$.ajax({
url: url,
data: data,
success(resultData) {
resolve(resultData);
},
error(err) {
reject(err);
}
})
}))
}
//需求:完成
//1.先獲取monster.json
//2.再獲取monster_detail_1.json
//3.再獲取monster_gf_2.json
get("data/monster.json").then((resultData) => {
//第一次ajax請求成功后的處理代碼
console.log("第1次ajax請求回傳的資料=", resultData);
return get(`data/monster_detail_${resultData.id}.json`);
}).then((resultData) => {
//第二次ajax請求成功后的處理代碼
console.log("第2次ajax請求回傳的資料=", resultData);
return get(`data/monster_gf_${resultData.gfid}.json`);
}).then((resultData) => {
//第三次ajax請求成功后的處理代碼
console.log("第3次ajax請求回傳的資料=", resultData);
//如果還有就繼續...
}).catch(err => {
console.log("請求出現例外=", err)
})
</script>
</head>
<body>
</body>
</html>
3.練習
分別使用Jquery-Ajax和Promise代碼重排,完成如下功能,發出3次ajax請求,獲取對應的資料,注意體會Promise發出多次Ajax請求的方便之處,
student_100.json
{
"id": 100,
"name": "jack",
"class_id": 10
}
class_10.json
{
"id": 10,
"name": "java工程師班級",
"student_num": 30,
"school_id": 9
}
school_9.json
{
"id": 9,
"name": "清華大學",
"address": "北京"
}
3.1jquery-ajax方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jquery-ajax</title>
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
//第一次ajax請求
$.ajax({
url: "data/student_100.json",
success(resultData) {
console.log("第一次ajax請求=", resultData);
//第二次ajax請求
$.ajax({
url: `data/class_${resultData.class_id}.json`,
success(resultData) {
console.log("第二次ajax請求=", resultData);
//第三次ajax請求
$.ajax({
url: `data/school_${resultData.school_id}.json`,
success(resultData) {
console.log("第三次ajax請求=", resultData);
},
error(err) {
console.log("第三次ajax請求出現例外=", err);
}
})
},
error(err) {
console.log("第二次ajax請求出現例外=", err);
}
})
},
error(err) {
console.log("第一次ajax請求出現例外=", err);
}
})
</script>
</head>
<body>
</body>
</html>
3.2Promise代碼重排
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>promise代碼重排</title>
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
//get方法也可以封裝到js工具類,重復使用
function get(url, data) {
return new Promise(((resolve, reject) => {
$.ajax({
url: url,
data: data,
success(resultData) {
resolve(resultData);
},
error(err) {
reject(err);
}
})
}))
}
//業務
get("data/student_100.json").then(resultData =https://www.cnblogs.com/liyuelian/p/> {
console.log("第1次回傳的資料=", resultData);
return get(`data/class_${resultData.class_id}.json`);
}).then(resultData =https://www.cnblogs.com/liyuelian/p/> {
console.log("第2次回傳的資料=", resultData);
return get(`data/school_${resultData.school_id}.json`);
}).then(resultData =https://www.cnblogs.com/liyuelian/p/> {
console.log("第3次回傳的資料=", resultData);
//如有需求可以繼續請求...
}).catch(err => {
console.log("promise異步請求例外=", err)
})
</script>
</head>
<body>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/541300.html
標籤:JavaScript
上一篇:獲取某地模型并用Cesium加載
