對于Promise的學習
1.什么是Promise
簡單來說Promise是異步編程的一種解決方案
Promise是ES6中的特性,
什么是異步操作?
網路請求中,對端服務器處理需要時間,資訊傳遞程序需要時間,不像我們本地呼叫算術函式一樣,這里的網路請求不是同步的有時延, 不能立即得到結果,
== 如何處理異步事件?==
對于網路請求這種,一般會使用回呼函式,在服務器端傳給我資料成功后,呼叫回呼函式,例如Ajax呼叫,
$.ajax({
sucess:function(){
...
}
})
如果碰到嵌套網路請求,例如第一次網路請求成功后回呼函式再次發送網路請求,這種代碼就會讓人含難受,
$.ajax({
sucess:function(){
$.ajax({
...
})
}
})
如果還需要再次的網路請求,那么又要嵌套一層,這樣的代碼層次不分明很難讀,也容易出問題,
2.Promise的基本使用
什么時候使用Promise
解決異步請求冗余這樣的問題,promise就是這樣封裝移步請求的,
Promise物件
new Promise((resolve, reject) =>
{})
Promise物件的引數是一個函式(resolve,reject) => {},這個函式又有兩個引數分別是resolve和reject,這兩個引數本身也是函式,后面還有回呼函式then(func)的引數也是一個函式,
模擬定時器的異步事件
用定時器模擬網路請求,定時一秒為網路請求事件,用console.log()表示需要執行的代碼,
//1.使用setTimeout模擬嵌套的第三次網路請求
setTimeout(() => {
//第一次請求
console.log("hello wk")
//第一次處理代碼
setTimeout(() => {
//第二次請求
console.log("hello meng")
//第二次處理代碼
setTimeout(() => {
//第三次請求
console.log("hello vue")
//第三次處理代碼
},1000)
},1000)
},1000)
一層套一層,看起來是不是很繞,
使用promise來處理異步操作
//引數 -> 函式
// resolve和reject本身也是函式
//then()的引數也是一個函式
new Promise((reslove,reject) => {
setTimeout(() => {
//第一次網路請求
resolve()
},1000)
}).then(() => {
console.log("hello wk")
//第一次處理代碼
return new promise((resolve, reject) => {
setTimeout(() => {
//第二次網路請求
resolve()
},1000).then(() => {
console.log("hello vuejs")//第二次處理代碼
return new Promise((resolve, reject) => {
setTimeout(() => {//第三次網路請求
resolve()
}, 1000)
}).then(() => {
console.log("hello java")//第三次處理代碼
})
})
})
})
是不是覺得代碼還要更復雜了?仔細看看第一個如果使用了多個就找不到對應的關系了,相反第二個流程就很清楚了,呼叫resolve()就能跳轉發到then()方法就能執行處理代碼,then()回呼的回傳值又是一個promise物件,層次很明顯,只要是then()必然是執行處理代碼,如果還有嵌套必然就是回傳了一個promise物件,這樣呼叫就像Java中的StringBuffer的append()方法一樣,鏈式呼叫,
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000).then(success => {
console.log(success)
})
})
setTimeout()模擬的是網路請求,而then()執行的是網路請求后的代碼,這就將網路請求和請求得到的回應后的操作分離了,每個地方干自己的事情,在resolve中傳參了,那么在then()方法中的引數就有這個引數,例如data,
網路請求中也會有失敗情況?例如網路堵塞,
如何處理失敗情況,此時就要用到reject()
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error message')
}, 1000).catch(error => {
console.log(error)
})
})
此時reject(error),catch()方法捕獲到reject()中的error,
合起來
new Promise((resolve, reject) => {
setTimeout(() => {
// 成功的時候呼叫resolve()
// resolve('hello world')
// 失敗的時候呼叫reject()
reject('error message')
}, 1000).then(success => {
console.log(success)
}).catch(error => {
console.log(error)
})
})
拿ajax來舉例子:
new Promise((resolve, reject) => {
$.ajax({
success:function(){
// 成功的時候呼叫resolve()
// resolve('hello world')
// 失敗的時候呼叫reject()
reject('error message')
}
}).then(success => {
console.log(success)
}).catch(error => {
console.log(error)
})
})
3.Promise的三種狀態

- pending:等待狀態,比如正在進行的網路請求還未回應,或者定時器還沒有到時間
- fulfill:滿足狀態,當我們主動回呼了resolve函式,就處于滿足狀態,并會回呼then()
- reject:拒絕狀態,當我們主動回呼reject函式,就處于該狀態,并且會回呼catch()
4.Promies的鏈式呼叫
-
網路請求回應結果為 hello ,列印hello
-
處理: hello world ,列印hello world
-
處理: hello world,vuejs ,列印hello world,vuejs
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 1000)
}).then(res => {
console.log(res)//列印hello
return new Promise(resolve => {
resolve(res + ' world')
}).then(res => {
console.log(res)//列印hello world
return new Promise(resolve => {
resolve(res + ',vuejs')
}).then(res => {
console.log(res)//列印hello world,vuejs
})
})
})
鏈式呼叫就是then()方法的回傳值回傳一個Promise物件繼續呼叫then(),此外還有簡寫Promise.resolve(),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 1000)
}).then(res => {
console.log(res)//列印hello
return Promise.resolve(res + ' world')
}).then(res => {
console.log(res)//列印hello world
return Promise.resolve(res + ',vuejs')
}).then(res => {
console.log(res)//列印hello world,vuejs
})
還可以直接省略掉Promise.resolve()
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 1000)
}).then(res => {
console.log(res)//列印hello
return res + ' world'
}).then(res => {
console.log(res)//列印hello world
return res + ',vuejs'
}).then(res => {
console.log(res)//列印hello world,vuejs
})
如果中途發生例外,可以通過catch()捕獲例外
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 1000)
}).then(res => {
console.log(res)//列印hello
return res + ' world'
}).then(res => {
console.log(res)
// return Promise.reject('error message')//發生例外
throw 'error message' //拋出例外
}).then(res => {
console.log(res)//列印hello world,vuejs
}).catch(error => {
console.log(error)
})
也可以通過throw拋出例外,類似java
throw 'error message' //拋出例外
5.Promies的all使用
有這樣一個情況,一個業務需要請求2個地方(A和B)的資料,只有A和B的資料都拿到才能走下一步,
ajax實作
$.ajax({
...//結果A
resultA = true
callback()
})
$.ajax({
...//結果B
resultB = true
callback()
})
//回呼函式
function callback(){
if(resultA&&resultB){
...
}
}
由于不知道網路請求A和網路請求B哪個先回傳結果,所以需要定義一個函式只有2個請求都回傳資料才回呼成功,
Promise實作
Promise.all([
new Promise((resolve, resjct) => {
$.ajax({
url: 'url1',
success: function (data) {
resolve(data)
}
})
}),
new Promise((resolve, resjct) => {
$.ajax({
url: 'url2',
success: function (data) {
resolve(data)
}
})
}).then(results => {
console.log(results)
})
])
上面是偽代碼,只是包裝了ajax,ajaxA和ajaxB的結果都放在resolve()中,Promise將其放在results中了,使用setTimeout模擬,
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {// 請求A
resolve('結果A')
}, 1000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {// 請求B
resolve('結果B')
}, 1000)
})
]).then(results => {
console.log(results)
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/208233.html
標籤:其他
上一篇:jQuery基礎知識
