淺解Promise

對於異步的解決方案

Promise

Promise是ES6新增的內置對象,一般使用Promise構造函數建立,Promise實例,解決異步問題。promise

1.Promise構造函數必須接收一個函數做爲參數,我將其稱爲executor函數,executor函數也能夠接收兩個參數,resolve和reject,它們是兩個函數由ECMAScript運行環境提供,無需本身部署。異步

//執行Promise函數,它返回一個promise實例對象
let promise=new Promise ((resolve,reject)=>{  
    console.log(1);
});

當咱們使用new建立一個構建一個Promise實例後,Promise實例內部的兩個屬性須要理解。函數

讓咱們輸出上方的promise實例spa

[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined

[[PromiseStatus]]:保存當前promise實例的狀態,可能值pending,resolved,rejectedcode

[[PromiseValue]]:在promise未完成狀態時,其值爲undefinde,當promise完成後,其值爲異步數據,或者錯誤信息。當執行了resolve(),[[PromiseValue]]的值就是resolve()傳入 的表達式的值,一般就是是咱們須要的值。當咱們使用了reject(),這個值爲reject()的傳入值,一般這個值爲錯誤提示對象

2.對於resolve和reject,它們的做用是判斷對象的狀態。而且它們調用時能夠接收一個參數。隊列

let promise=new Promise ((resolve,reject)=>{  
    console.log(1);
    resolve('成功');
});

當調用了resolve或reject ,promise實例的[[PromiseStatus]]將發生改變。ip

如今,讓咱們更加詳細的去了解Promise

promise狀態

一個Promise對象的當前狀態必須爲一下三種狀態的一種:Pending(等待狀態),Fulfilled(執行狀態),Rejected(拒絕狀態)部署

  • Pending:處於Pending狀態時,promise能夠知足如下條件

​ 能夠由Pending轉爲Fulfilled或Rejected ,回調函數

  • Fulfilled:處於Fulfilled狀態時,promise知足如下條件

​ 1.不可再變爲其它狀態。

​ 2.必須有一個不可被改變的值。

  • Rejected

​ 1.不可再變爲其它狀態。

​ 2.必須有一個不可被改變的值。

如何理解Promise A + 規範中的這三個狀態及其規則。

Promise對象的兩個內部屬性能夠很好幫咱們去解釋理解。

[[PromiseStatus]] ,[[PromiseValue]]

如今,進行Promise第一步,新建一個Promise對象,對象兩個內部屬性被初始化

[[PromiseStatus]] :Pending

[[PromiseValue]]:undefined

此時是規範中的第一種狀態,OK,根據規範的Pending狀態的條件,咱們能夠去改變其狀態。

executor函數在Promise對象建立後當即執行

假若咱們在executor函數執行了resolve()函數,而且,將一個 表達式(Expression)做爲其參數傳入。此時內部屬性值的變化

[[PromiseStatus]]:resolved

[[PromiseValue]]:<表達式的值>

此時,Promise對象的狀態有Pending變爲Fulfilled.通俗點說,就是由等待變爲成功。根據Promise A+ 的Fulfilled狀態的規範條件,此時,不管接下來在遇到什麼狀況,都不會去改變它的狀態!,而且Promise對象將會有一個值,Yes,這個值就是咱們須要的值,準確的說,它就是那個傳入的表達式的值,而且這個值經過resolve()函數存入了[[PromiseValue]]屬性中。咱們沒法直接去使用它,而是經過then()去獲取

讓咱們來看個例子

let  p1 = new Promise((res,rej)=>{
 res((() => {
        return '成功了';
        })())
    })
console.log(p1); 
//輸出
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "成功了"
假若咱們在executor函數執行了reject()函數,而且,將一個 表達式(Expression)做爲其參數傳入。此時內部屬性值的變化
let  p2 = new Promise((res,rej)=>{
 rej((() => {
      return '失敗了';
    })())
})
console.log(p2);
// promise對象的兩個屬性
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: "失敗了"

此時,Promise對象的狀態有Pending變爲Fulfilled,由等待變爲失敗,根據Promise A+ 的Fulfilled狀態的規範條件,此時,不管接下來在遇到什麼狀況,都不會去改變它的狀態!而且Promise對象將會有一個值,一樣也是那個傳入的表達式的值,不過咱們將這個值稱爲拒因或失敗緣由

注意:resolvereject並不會終結 Promise 的executor函數的執行

咱們已經在executor函數中執行了resolve或reject函數,狀態發生改變,內部屬性值也發生了改變

如今,該啓動then()方法和 catch()方法了。

then()

它有兩個函數做爲參數,一般,咱們只使用第一個函數來獲取[[PromiseStatus]]的值爲"resolved"的對象的[[PromiseValue]]值,回調函數接收一個參數,此參數就是[[PromiseValue]]值

let  p1 = new Promise((res,rej)=>{
 res((() => {
        return '成功了';
        })())
    }).then(data=>{
        console.log(data) 
    })

注意 : then() 方法產生一個微任務,其回調將會被置入上一個宏任務隊列後。

cathc()

[[PromiseStatus]]爲reject時,調用此方法。

它接收一個函數做爲參數,此函數接收一個參數,該參數就是拒因

let  p2 = new Promise((res,rej)=>{
 rej((() => {
        return '失敗了';
        })())
    }).then(data=>{
        console.log(data) 
    }).catch(error=>console.log(error))

如今大體瞭解了Promise是怎麼回事了 Good!

還有注意 :不管如何,在使用Promise對象時,加上catch(),不然你極可能不知道錯誤究竟是出在哪裏

相關文章
相關標籤/搜索