萌新如何理解Promise對象

一.Promise是啥

1.阮大佬的解釋

2.看不懂,直接打印

能夠看到,這是個構造函數,本身有all,race,reject,resolve方法,原型上有 then,catch方法javascript

3.特色

  • 只有三種狀態pending(正在進行),fulfilled(已成功),rejected(已失敗)
  • 只有兩種狀態轉換
    • pending===>fulfilled
    • pending===>rejected
  • 狀態一旦轉換,不會再改變,且promise對象沒法自動銷燬,任什麼時候候均可以獲取執行結果

二.啥也無論,用了再說

1.new一個先

let p = new Promise((resolve,reject)=>{
    console.log('123')
    setTimeout(()=>{
        console.log('執行結束')
        resolve(321)
    },2000)
})
複製代碼

結果:
java

上面先執行了隨便什麼操做,兩秒後執行了resolve,打印了執行結束es6

啥是resolve和reject?

已經知道這是在構造函數Promise上的方法,es6標準上講resolve是將異步操做狀態從pending轉爲fulfilled,而reject是將狀態從pending轉爲rejectedajax

看不懂?那繼續show you the code數組

2.then方法,以及爲何promise支持鏈式操做?

show you the code

p.then((data)=>{
    console.log(data)
})
複製代碼

看結果返回了一個promise對象,咱們知道promise原型上有then方法,所以能夠鏈式操做,很爽!!!promise

打印了321,說明resolve傳出的數據咱們能夠在then中操做,所以即可以在then中爲異步操做的成功或失敗狀態後設置回調函數,讓代碼看起來更像同步操做.(解決了回調地獄這個事兒)異步

關於什麼是回調地獄,參考:async

[juejin.im/post/5ae7aa…]:函數

簡單理解就是函數做爲參數層層被調用,會是代碼耦合度極高,不利於維護post

提問:還有什麼別的方法能夠解決嘛?

tip:es7中的async/await =====>這被稱爲解決異步問題的終極方法

3.造一個函數做爲參數層層調用的例子

小明跟爸爸說小明要吃烤肉,爸爸說讓小明去買材料,買完材料回來爸爸製做,製做完小明就趕忙吃了溜(就不刷碗!!!!)

先定義幾個方法

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)
})
複製代碼

運行結果

一步一步,上一步函數的調用結果做爲下一步的參數,將異步操做以同步操做的流程表達出來,避免層層嵌套,完美.

4.reject是啥?

通過上面的例子,應該大概瞭解了promise是啥,可是裏面好像還有個reject咱們還沒看,來,繼續上面的例子

衆所周知,小明是一個調皮的可是注意力不集中的好孩子,在路上,他發現了好甜的水果糖,因而買了水果糖,結果回到家到了第二調用,便帶了個error

show you the code

// 改一下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傳過來的數據.

5.catch?

單詞的一次就是捕獲,因此做用是捕獲異常,參數爲異常處理函數,也就是跟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捕獲,並作處理,而後能夠繼續運行代碼.

6.race和all方法

all方法

仍是用小明的例子

咱們先把延時時間改一下,好比async1改成4s,async2改成3s,async3改成2s

Promise.all([async1(),async2(),async3()])

// all裏傳的參數爲promise實例的數組
複製代碼

看結果

all方法提供的是並行執行異步操做的能力

Promise.all()方法的參數爲一個數組,數組裏各元素均爲promise實例,若是不是,會先轉換爲promise實例.

注意

  • 所有執行完異步操做纔會進入then處理每一個異步操做的返回數據.

簡單理解就是以跑的慢的爲準,跑的慢的跑完了才一塊兒處理返回結果.

使用場景

  • 加載靜態資源所有完成後才須要渲染處理的時候

race方法

相對all方法,這個就是跑的快的爲準,有跑完了的就直接執行then裏處理函數

因而上面的代碼改用race方法後

Promise.race([async1(),async2(),async3()]).then((datas)=>console.log(datas))
複製代碼

結果

async3執行的最快,跑完後便直接處理打印了resolve返回的數據==>'就不刷碗'

使用場景

  • 給ajax等異步操做請求設置超時時間

至此,最經常使用的promise的方法都已經介紹完畢.

相關文章
相關標籤/搜索