1. 程式人生 > 其它 >對Promise的個人理解

對Promise的個人理解

技術標籤:jsjs

Promise

三種狀態:pending、fulfilled、rejected
只能pending——>fulfilled或者pending——>rejected,且不可逆。

let promise=new Promise(function(resolve,reject){
        // resolve函式是當promise狀態由pending轉為fulfilled時執行
        // reject函式是promise狀態由pending轉為rejected時執行
        // 只有當resolve或reject函式執行之後,此時promise的狀態才發生變化,才能執行promise.then或promise.catch方法,且將resolve/reject的引數傳遞給then或catch方法
//既然如此,直接在建構函式Promise傳遞的引數 resolve函式中處理非同步操作返回的資料就可以,為什麼還要把資料在傳遞給then方法呢? //hhh 個人理解這是為了解決回撥地獄問題,我們可以在then中返回一個Promise例項,這樣就會出現then的鏈式寫法。 resolve('成功'); }) promise.then(data=>{ console.log(data); return new Promise((resolve,reject)=>{ console.
log('我是第二個promise例項') // resolve('2222') reject('333') }) }).then(function(data){ console.log('222111') console.log(data) },function(error){ console.log(error); })

輸出結果是
在這裡插入圖片描述
當把resolve('成功')改成reject('失敗') 時,輸出的結果是
在這裡插入圖片描述
所以我們可以看出,前一個promise例項的狀態會影響後面例項的狀態

Promise.prototype上的一些方法

  1. Promise.prototype.then
  2. Promise.prototypev.catch
  3. Promise.prototype.finally
//三種方法返回的都是Promise例項,後面可以繼續跟then方法
Promise(resolve,reject=>{
}).then() //一般用來執行resolved的回撥函式
.catch() //捕獲錯誤或異常資訊
.finally()//不管Promise例項的狀態如何都會執行

Promise上的方法

  1. Promise.all
  2. Promise.race
  3. Promise.allSettled
  4. Promise.any
  5. Promise.resolve
  6. Promise.reject
//建構函式上的方法
let p=Promise.all([p1,p2,p3]);
p.then()
//1.只有p1、p2、p3的狀態都變成fulfilled,p的狀態才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回撥函式。
//2.只要p1、p2、p3之中有一個被rejected,p的狀態就變成rejected,此時第一個被reject的例項的返回值,會傳遞給p的回撥函式。

let r=Promise.race([p1,p2,p3]);
//只要p1、p2、p3之中有一個例項率先改變狀態,p的狀態就跟著改變。那個率先改變的 Promise 例項的返回值,就傳遞給p的回撥函式

let s=Promise([p1,p2,p3]);
s.then() //一定是resolve
//Promise.allSettled()方法接受一組 Promise 例項作為引數,包裝成一個新的 Promise 例項。只有等到所有這些引數例項都返回結果,不管是fulfilled還是rejected,包裝例項才會結束。
//該方法返回的新的 Promise 例項,一旦結束,狀態總是fulfilled,不會變成rejected

//我們不關心非同步操作的結果,只關心這些操作有沒有結束。這時,Promise.allSettled()方法就很有用。

let a=Promise.any([p1,p2,p3])
//該方法接受一組 Promise 例項作為引數,包裝成一個新的 Promise 例項返回。
//只要引數例項有一個變成fulfilled狀態,包裝例項就會變成fulfilled狀態;
//如果所有引數例項都變成rejected狀態,包裝例項就會變成rejected狀態。


//Promise.resolve(param):將物件轉為 Promise 物件
1.如果引數是一個promise例項,則原樣返回
2.如果是一個thenable物件(具有then方法的物件),則會將這個物件轉為promise物件並立即執行thenable物件中then方法,此時promise物件的狀態就會發生變化
3.引數有,但啥也不是。 如果引數是一個原始值,或者是一個不具有then()方法的物件,則Promise.resolve()方法返回一個新的 Promise 物件,狀態為resolved。
4.沒有引數。Promise.resolve()方法允許呼叫時不帶引數,直接返回一個resolved狀態的 Promise 物件。

Promise.reject(param):返回一個promise例項,且該例項的狀態為rejected。param會原封不動的作為引數傳遞給catch的reject回撥函式。

用promise實現簡單的封裝ajax

    function Ajax(url){
        let promise =new Promise((resolve,reject)=>{  
            let xhr=new XMLHttpRequest();
            xhr.open('GET',url);
            xhr.responseType='json';
            xhr.setRequestHeader('Accept','application/json');
            xhr.onreadystatechange=function(){
                if(xhr.readyState===4 &&xhr.status===200){
                    resolve(xhr.response)
                }else{
                    reject(new Error(this.statusText))
                }
            }
            xhr.send();
        })
        return promise
    }
    Ajax('https://baidu.com').then(function(json){
        console.log(json)
    }).catch(function(error){
        console.log(error)
    })