1. 程式人生 > 資訊 >特斯拉美國得州工廠接近投產,Model Y 車身鑄件現廠區

特斯拉美國得州工廠接近投產,Model Y 車身鑄件現廠區

什麼是promise

promise是一個物件,它代表了一個非同步操作的最終完成或者失敗

promise產生的原因

promise的誕生是為了解決回撥地獄,常見的回撥地獄:Ajax的並行與序列

  • Ajax序列:只有第一個請求成功才能執行第二個,第二個成功才能執行第三個...最後一個成功後才能拿到每一次的請求的所有資料
    $.ajax({
        url:'/api1/',
        success:function(result){
           $.ajax({
               url:'/api2',
               success: result=>{
                   $.ajax({
                       url:'/api3',
                       success: result=>{
                           console.log(result);
                       }
                   })
               }
           })
    }
    })
  • Ajax的並行:三個請求可以同時傳送,但需要等到所有請求成功從能做一件事情
    var count = 0;
    function func(){
        console.log('已完成')
    }
    function test(){
       if(count>=3){
           func();
       }
    }
    $.ajax({
        url:'/api1/',
        success: result=>{
            count++;
           test();
        }
    })
    $.ajax({
        url:'/api2/',
        success: result=>{
            count++;
            test();
        }
    })
    $.ajax({
        url:'/api3/',
        success: result=>{
            count++;
            test();
        }
    })

Promise的建立

Promise 物件是由關鍵字 new 及其建構函式來建立的。該建構函式會把一個叫做“處理器函式”(executor function)的函式作為它的引數。

  • new promise的時候就會把executor執行
  • promise會給executor傳遞兩個引數resolve(),reject()
    • resolve(): 它執行代表promise處理的非同步事情是成功的,並把promise的狀態改為fulfillde(resolved)
    • reject(): 它執行代表promise處理的非同步事情是失敗的,並把promise的狀態改為rejected
  • executor函式中放的是當前要處理的非同步操作。
    let promiseExamp =new Promise((resolve,reject)=>{
        //一般存放的是即將要處理的非同步任務,任務成功我們執行resolve,任務失敗執行reject
        setTimeout(()=>{
            if(Math.random()<0.5){
                reject('呵呵)
            }
            resolve('哈哈')
        },1000)
    });

Promise的三種狀態

  • pending: 初始狀態(new promise後的狀態)
  • fulfilled(resolved): 成功狀態(在executor函式中把resolve執行,就告知promise當前非同步操作是成功的)
  • rejected: 失敗狀態(在executor函式中把reject執行,就告知promise當前非同步操作是失敗的)

Promise.prototype

  • then: 設定成功或失敗後執行的方法(成功或失敗都可以設定,也可以只設置一個)
  pro.then([success],[error])
  pro.then([success])
  pro.then(null,[error])
  • catch: 設定失敗後執行的方法
  • finally: 不論成功還是失敗都能執行的方法

promise的執行流程

    let promiseExamp =new Promise((resolve,reject)=>{
        //一般存放的是即將要處理的非同步任務,任務成功我們執行resolve,任務失敗執行reject
        setTimeout(()=>{
            if(Math.random()<0.5){
                reject('呵呵')
            }
            resolve('哈哈')
        },1000)
    });
    promiseExamp.then(function success(result){
         console.log(result);
    },function error(reason){
        console.log(reason);
    })


鏈式寫法

執行then/catch/finally返回的結果是一個全新的promise例項,所以可以鏈式寫下去:下一個then中哪個方法被執行,由上一個then中某個方法執行的結果來決定(then中某個方法能夠正常執行,新的promise例項的狀態為fulfilled),上一個then中某個方法的返回值會傳遞給下一個then的某一個方法

    new Promise((resolve,reject)=>{
        resolve(100);
    }).then(result=>{
        console.log(result);
    }).catch(error=>{
        console.log(error)
    })
    //這種寫法的優點是:當then方法在執行過程報錯,這個時候會讓then建立的promise例項變為失敗狀態,並且把報錯的原因修改此promise例項的value值。
    new Promise((resolve,reject)=>{
        resolve(100);
    }).then(result=>{
        console.log(result);  //100
        return result*10;
    }).catch(error=>{
        console.log(error);
        return error/10
    }).then(A=>{
        console.log('A='+A);  //A:1000
    },B=>{
        console.log('B='+B);
    })

如果當前promise例項的狀態確定後,都會到對應的then中找方法,如果then中沒有對應的這個方法,則會向下順延(順延的原因:上一個then中沒有成功的函式promise內部會幫我們自動建立一個成功的函式,讓其執行後的狀態還是fulfilled)

如果一個方法中返回的是一個新的promise例項,它會按照這個例項的最終狀態和結果,決定下一個then中執行誰。

    new Promise((resolve,reject)=>resolve(x)).then(x=>{
        return new Promise();
    })

Promise常見的方法

  1. promise.all()

promise.all([promise1,promise2,...])

  • All中存放的是多個promise例項
  • 這個方法返回一個新的promise物件
  • 當引數列表中所有的promise例項的狀態都為fulfilled,讓新的例項狀態也變為fulfilled,並且把所有promise成功獲取的結果,儲存為一個數組(順序和最開始編寫引數的順序一致),讓新的例項的valve值等於這個陣列。
  • 只要有一個狀態為rejected,那麼新的例項狀態就為rejected
  • 都成功才會通知then中第一個方法執行,只要有一個失敗就會通知then中第二個方法或catch中方法執行
  1. promise.race()

看哪個promise狀態最先處理完(成功或失敗),以最先處理完的為主