能夠看到,這是個構造函數,本身有all,race,reject,resolve方法,原型上有 then,catch方法javascript
let p = new Promise((resolve,reject)=>{
console.log('123')
setTimeout(()=>{
console.log('執行結束')
resolve(321)
},2000)
})
複製代碼
結果:
java
上面先執行了隨便什麼操做,兩秒後執行了resolve,打印了執行結束es6
已經知道這是在構造函數Promise上的方法,es6標準上講resolve是將異步操做狀態從pending轉爲fulfilled,而reject是將狀態從pending轉爲rejectedajax
看不懂?那繼續show you the code數組
p.then((data)=>{
console.log(data)
})
複製代碼
看結果返回了一個promise對象,咱們知道promise原型上有then方法,所以能夠鏈式操做,很爽!!!promise
打印了321,說明resolve傳出的數據咱們能夠在then中操做,所以即可以在then中爲異步操做的成功或失敗狀態後設置回調函數,讓代碼看起來更像同步操做.(解決了回調地獄這個事兒)異步
關於什麼是回調地獄,參考:async
簡單理解就是函數做爲參數層層被調用,會是代碼耦合度極高,不利於維護post
tip:es7中的async/await =====>這被稱爲解決異步問題的終極方法
小明跟爸爸說小明要吃烤肉,爸爸說讓小明去買材料,買完材料回來爸爸製做,製做完小明就趕忙吃了溜(就不刷碗!!!!)
let async1 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('買材料')
resolve('買完材料了')
}, 2000)
})
return p
}
let async2 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('製做')
resolve('製做完成,趕忙吃')
}, 2000)
})
return p
}
let async3 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('吃完趕忙溜')
resolve('就不刷碗')
}, 2000)
})
return p
}
複製代碼
show you the code
async1().then((data) => {
console.log(data)
return async2()
}).then((data) => {
console.log(data)
return async3()
}).then((data) => {
console.log(data)
})
複製代碼
運行結果
一步一步,上一步函數的調用結果做爲下一步的參數,將異步操做以同步操做的流程表達出來,避免層層嵌套,完美.
通過上面的例子,應該大概瞭解了promise是啥,可是裏面好像還有個reject咱們還沒看,來,繼續上面的例子
衆所周知,小明是一個調皮的可是注意力不集中的好孩子,在路上,他發現了好甜的水果糖,因而買了水果糖,結果回到家到了第二調用,便帶了個error
// 改一下async1()
let async1 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('買材料')
console.log('看到糖果')
console.log('買了糖果')
if(/*買對了*/ 0){
resolve('買了材料')
}else{
reject('買了糖果')
}
}, 2000)
})
return p
}
// 描述故事
async1().then((data) => {
console.log(data)
return async2()
},(err)=>{
console.log('買錯了,快滾')
return
})
//爲了描述上面的例子,這裏只作了第一步調用
複製代碼
結果:
由結果看,then(parm1,parm2)的兩個參數,第一個爲處理resolve的情況,給resolve添加函數處理,而第二個參數爲處理reject的情況,兩個參數都爲處理函數.
第一個處理函數的參數爲resolve傳過來的數據,第二個的參數爲reject傳過來的數據.
單詞的一次就是捕獲,因此做用是捕獲異常,參數爲異常處理函數,也就是跟then的第二個參數同樣,所以再也不贅述,可是catch有本身的獨特的做用(否則憑啥存在)
話很少說,show you the code
const fun = () => {
let p = new Promise((resolve, reject) => {
resolve(123)
})
return p
}
fun().then((data)=>{
console.log(data)
console.log(names)
})
複製代碼
上面的例子運行會報names is not defined 的錯誤,並且不會繼續運行了,若是後面有代碼會直接中斷,而若是加了catch
fun().then((data)=>{
console.log(data)
console.log(names)
}).catch((res)=>{
console.log('出錯咯')
}).then((data)=>{
console.log('123')
})
複製代碼
看結果
由此,代碼出錯,會被catch捕獲,並作處理,而後能夠繼續運行代碼.
仍是用小明的例子
咱們先把延時時間改一下,好比async1改成4s,async2改成3s,async3改成2s
Promise.all([async1(),async2(),async3()])
// all裏傳的參數爲promise實例的數組
複製代碼
看結果
Promise.all()方法的參數爲一個數組,數組裏各元素均爲promise實例,若是不是,會先轉換爲promise實例.
注意
簡單理解就是以跑的慢的爲準,跑的慢的跑完了才一塊兒處理返回結果.
使用場景
相對all方法,這個就是跑的快的爲準,有跑完了的就直接執行then裏處理函數
因而上面的代碼改用race方法後
Promise.race([async1(),async2(),async3()]).then((datas)=>console.log(datas))
複製代碼
結果
async3執行的最快,跑完後便直接處理打印了resolve返回的數據==>'就不刷碗'
使用場景
至此,最經常使用的promise的方法都已經介紹完畢.