ES6-Promise

qq_45962090發表於2020-10-26

一、基本概念

1.什麼是Promise?

Promise 是非同步程式設計的一種解決方案,其實是一個建構函式,自己身上有all、reject、resolve這幾個方法,原型上有then、catch等方法。

2.階段及狀態

1. ES6 將某一件可能發生非同步操作的事情
分為兩個階段:unsettledsettled

非同步操作階段

  • unsettled: 未決階段,表示事情還在進行前期的處理,並沒有發生通向結果的那件事
  • settled:已決階段,事情已經有了一個結果,不管這個結果是好是壞,整件事情無法逆轉

2. ES6將事情劃分為三種狀態: pending、resolved、rejected
狀態

  • pending: 掛起,處於未決階段,則表示這件事情還在掛起(最終的結果還沒出來)。
  • resolved:已處理,已決階段的一種狀態,表示整件事情已經出現結果,並是一個可以按照正常邏輯進行下去的結果。
  • rejected:已拒絕,已決階段的一種狀態,表示整件事情已經出現結果,並是一個無法按照正常邏輯進行下去的結果,通常用於表示有一個錯誤。

3. 當事情達到已決階段後,通常需要進行後續處理,不同的已決狀態,決定了不同的後續處理。
階段

  • resolved狀態:這是一個正常的已決狀態,後續處理表示為 thenable
  • rejected狀態:這是一個非正常的已決狀態,後續處理表示為 catchable

後續處理可能有多個,因此會形成作業佇列,這些後續處理會按照順序,當狀態到達後依次執行。

4. 整件事稱之為Promise
Promise

3.特點

(1)只有非同步操作可以決定當前處於的狀態,並且任何其他操作無法改變這個狀態;
(2)一旦狀態改變,就不會在變。狀態改變的過程只可能是:從pending變為fulfilled和從pending變為rejected。如果狀態發生上述變化後,此時狀態就不會在改變了,這時就稱為resolved(已定型)
始終記住,無論是階段,還是狀態,是不可逆的!

二、基本用法

1.建立一個Promise物件

let pro = new Promise(function(resolve, reject){
		//做一些非同步操作
		setTimeout(function(){
			console.log('執行完成Promise');
			resolve('要返回的資料可以任何資料例如介面返回資料');
		}, 2000);
	});

其執行過程是:執行了一個非同步操作,也就是setTimeout,2秒後,輸出“執行完成”,並且呼叫resolve方法。
我們通過then方法,分別指定resolved狀態和rejected狀態的回撥函式。

pro.then(data => {
			 // 這是thenable函式 如果當前Promise是resolved狀態那麼then會立即執行
            // 如果當前是未決階段 會加入到作業佇列裡面 等待成為resolved狀態
        }), err => {
            // 這是catchable函式 如果當前Promise是rejected狀態那麼err會立即執行
            // 如果當前是未決階段 會加入到作業佇列裡面 等待成為rejected狀態
        }

2.以函式的方式建立Promise

 function biaobai(god) {
            return new Promise((resolve, reject) => {
                console.log(`小明向${god}發出請求`);
                setTimeout(function() {
                    if (Math.random() > 0.2) {
                        resolve(true);
                    } else {
                        resolve(false);
                    }
                }, 1000)
            })
 }
 biaobai("小紅").then(data => {
            console.log(data);
 })
  • 1.未決階段裡面的處理函式是同步的,會立即執行
  • 2.thenable catchable是非同步,就算是會立即執行,也會加入到事件佇列中等待執行,並且加入的佇列是微佇列
  • 3.在未決階段中,如果出現未捕獲的錯誤會將狀態推向rejected
  • 4.一旦推向了已決狀態,無法再對狀態進行任何更改

3.Promise串聯

let pro1 = new Promise((resolve,reject)=>{
            throw 1
        })
        let pro2 = pro1.then(data=>{
            return data*2
        },err=>{
            return err*3
        })

        
        pro2.then(data=>{
            console.log(data*2);
            
        },err =>{
            console.log(err*3);
        })
       
       
        pro1.catch(err=>{
            return err *2;
        })

Promise物件中,無論是then方法還是catch方法,他們都具有返回值,返回的是一個全新的Promise物件,他們的狀態滿足下面兩個規則
1.如果當前的Promise是未決狀態,得到新的是掛起狀態
2.如果當前的Promise是已決狀態,會執行響應的後續處理,並將後續函式處理的結果(返回值)作為resolved狀態資料應用到新的Promise中,如果後續函式發生錯誤,把返回值作為rejected應用到新的Promise中
後續的Promise一定會等到前面Promise有了後續處理結果後,才會變成已決狀態

如果前面的Promise的後續處理,返回值是一個Promise則新新的Promise狀態和後續處理返回的Promise狀態保持一致。