網(wǎng)絡(luò)請求的回調(diào)地獄
我們來考慮下面的場景(有夸張的成分):
我們需要通過一個url1從服務(wù)器加載一個數(shù)據(jù)data1,data1中包含了下一個請求的url2
我們需要通過data1取出url2,從服務(wù)器加載數(shù)據(jù)data2,data2中包含了下一個請求的url3
我們需要通過data2取出url3,從服務(wù)器加載數(shù)據(jù)data3,data3中包含了下一個請求的url4
發(fā)送網(wǎng)絡(luò)請求url4,獲取最終的數(shù)據(jù)data4

上面的代碼有什么問題嗎?
正常情況下,不會有什么問題,可以正常運行并且獲取我們想要的結(jié)果。
但是,這樣代碼難看而且不容易維護(hù)。
我們更加期望的是一種更加優(yōu)雅的方式來進(jìn)行這種異步操作。
如何做呢?就是使用Promise。
Promise可以以一種非常優(yōu)雅的方式來解決這個問題。
promise的基本使用
使用setTimeOut模擬網(wǎng)絡(luò)請求
//第一次網(wǎng)絡(luò)請求
setTimeout(()=>{
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
//第二次網(wǎng)絡(luò)請求
setTimeout(()=>{
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
},1000)
//第三次網(wǎng)絡(luò)請求
setTimeout(()=>{
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
},1000)
},1000)
這樣的代碼難看,可以使用Promise
new Promise((resolve, reject)=>{
//第一次網(wǎng)路請求
setTimeout(()=>{
resolve();
},1000)
}).then(data => {
//第一次拿到結(jié)果的處理代碼
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
return new Promise((resolve, reject)=>{
//第二次網(wǎng)路請求
setTimeout(()=>{
resolve();
},1000)
},1000)
}).then(data => {
//第二次拿到結(jié)果的處理代碼
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
return new Promise((resolve, reject)=>{
//第三次網(wǎng)路請求
setTimeout(()=>{
resolve();
},1000)
},1000)
}).then(data => {
//第三次拿到結(jié)果的處理代碼
console.log('hello world');
console.log('hello world');
console.log('hello world');
console.log('hello world');
})
使用promise鏈?zhǔn)秸{(diào)用,代碼更加清晰
Promise三種狀態(tài)
首先, 當(dāng)我們開發(fā)中有異步操作時, 就可以給異步操作包裝一個Promise
異步操作之后會有三種狀態(tài)
我們一起來看一下這三種狀態(tài):
pending:等待狀態(tài),比如正在進(jìn)行網(wǎng)絡(luò)請求,或者定時器沒有到時間。
fulfill:滿足狀態(tài),當(dāng)我們主動回調(diào)了resolve時,就處于該狀態(tài),并且會回調(diào).then()
reject:拒絕狀態(tài),當(dāng)我們主動回調(diào)了reject時,就處于該狀態(tài),并且會回調(diào).catch()


鏈?zhǔn)秸{(diào)用簡寫
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000)
}).then(data => {
console.log(data,'第一層的10行處理代碼');
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(data + '111');
},1000)
},1000)
}).then(data => {
console.log(data,'第二層的10行處理代碼');
})
return new Promise((resolve, reject)=>可以簡寫為 promise.resolve,promise.reject
簡寫為:
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000)
}).then(data => {
console.log(data,'第一層的10行處理代碼');
return Promise.resolve(data + '111');
}).then(data => {
console.log(data,'第二層的10行處理代碼');
})
還可以再次簡寫:return Promise.resovle(data)簡寫為return data
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000)
}).then(data => {
console.log(data,'第一層的10行處理代碼');
return data + '111';
}).then(data => {
console.log(data,'第二層的10行處理代碼');
})
all的用法
Promise的all方法提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完后才執(zhí)行回調(diào)
Promise.all([
//操作1
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('result1');
},1000)
}),
//操作2
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('result2');
},1000)
}),
]).then(results =>{
console.log(results);
})
操作1、操作2執(zhí)行完才會調(diào)用then
參考:
https://www.jiagou1216.com/life/front/801.html
https://www.cnblogs.com/lvdabao/p/jquery-deferred.html