1. 程式人生 > 遊戲 >滑板遊戲《Session》將於9月22日正式發售 離開搶先體驗

滑板遊戲《Session》將於9月22日正式發售 離開搶先體驗

Promise

1.Promise的前置知識

  • 程序(廠房)

    • 程式的執行環境
  • 執行緒(工人)

    • 執行緒是實際進行運算的東西
  • 同步

    • 通常情況程式碼都是自上向下一行一行執行的
    • 前邊的程式碼不執行後邊的內碼表不會執行
    • 同步的程式碼執行會出現阻塞的情況
    • 一行程式碼執行慢會影響到整個程式的執行
  • 解決同步的問題:

    • java python

      • 通過多執行緒來解決,但是一般消耗資源比較多
    • node.js

      • 通過非同步方式來解決

        我們可以這麼理解:客人就好比我們請求的資料,服務員就好比客戶端,廚師就好比伺服器,我們現在客人點菜,服務員接收到菜的名稱資訊,給廚師說,廚師開始做,廚師在做的時候,客人一直等,不能幹其他的事情,這就是同步,只能幹一件事,我們現在利用非同步的方式,可以讓客人在課桌上等著菜來,也不影響服務員接收下一個客人的點菜,這樣就可以很好的處理同步所帶來的堵塞問題

  • 非同步

    • 一段程式碼的執行不會影響到其他的程式

    • 非同步的問題:

      • 非同步的程式碼無法通過return來設定返回值
    • 特點:

      1. 不會阻塞其他程式碼的執行

      2. 需要通過回撥函式來返回結果

        function sum(a, b, cb) {
            setTimeout(() => {
                cb(a + b)  //呼叫箭頭函式,把結果作為回撥函式的引數
            }, 1000)
        }
        
        sum(123, 456, (result)=>{
            console.log(result)
        })
        
    • 基於回撥函式的非同步帶來的問題

      1. 程式碼的可讀性差

      2. 可除錯性差(造成回撥地獄)

        sum(123, 456, (result)=>{
            sum(result, 7, (result)=>{
                sum(result, 8, result => {
                    sum(result, 9, result => {
                        sum(result, 10, result => {
                            console.log(result)
                        })
                    })
                })
            })
        })
        
    • 解決問題:

      • 需要一個東西,可以代替回撥函式來給我們返回結果
      • Promise橫空出世
        • Promise是一個可以用來儲存資料的物件
          • Promise儲存資料的方式比較特殊,這種特殊的方式使得Promise可以用來儲存非同步呼叫的資料

2.Promise介紹

非同步呼叫必須要通過回撥函式來返回資料,當我們進行一些複雜的呼叫時,會出現回撥地獄

問題:

​ 非同步必須通過回撥函式來返回結果,回撥函式增加就不容易處理

  • Promise
    • Promise可以幫助我們解決非同步中的回撥函式的問題
    • Promise就是一個用來儲存資料的容器
      • 它擁有著一套特殊的儲存資料的方式
      • 這個方式使得它裡面可以儲存非同步呼叫的結果
  1. 建立Promise

    1. 建立Promise時,建構函式中需要一個函式作為引數

    2. Promise建構函式的回撥函式,它會在建立Promise時呼叫,呼叫時會有兩個引數傳遞進去

      const promise = new Promise((resolve, reject)=>{
          // resolve 和 reject 是兩個函式,通過這兩個函式可以向Promise中儲存資料
          // resolve 在執行正常的時候儲存資料, reject 是在執行錯誤的時候儲存資料
          resolve('我是正常執行的時候呼叫的')
          reject('我是錯誤執行的時候呼叫的')
          //通過函式來訪問Promise中新增資料,好處就是可以用來新增非同步呼叫的資料
          setTimeout(()=>{
              resolve('非同步中呼叫資料')
      	},2000)
          throw new Error('出錯了,呼叫的是reject')
      })
      
  2. 從Promise中讀取資料

    1. 可以通過Promise的例項方法then來讀取Promise中儲存的資料

    2. then需要兩個回撥作為引數,回撥函式來獲取Promise中的資料

      1. 通過resolve儲存的資料,會呼叫第一函式返回,可以在第一個函式中編寫處理資料的程式碼

      2. 通過reject儲存資料或者出現異常時,會呼叫第二個函式返回,可以在第二個函式中編寫處理異常的程式碼

        promise.then((result)=>{
            console.log('1',result)
        },(reson)=>{
            console.log('2',reason)
        })
        
  3. Promise中維護了兩個隱藏屬性:

    1. PromiseResult
      1. 用來儲存資料
    2. PromiseState
      1. 記錄Promise的狀態(三種狀態)
        1. pending(進行中)
        2. fulfilled(完成)通過resolve儲存資料時
        3. rejected(拒絕,出錯了)出錯了或通過reject儲存資料時
      2. state只能修改一次,修改以後永遠不會在變
    3. 流程:
      1. 當Promise建立時,PromiseState初始值為pending
        1. 當通過resolve儲存資料時 PromiseState 變為fulfilled(完成)
          1. PromiseResult變為儲存的資料
        2. 當通過reject儲存資料或出錯時 Promise 變為rejected(拒絕)
          1. PromiseResult變為儲存的資料 或 異常物件
      2. 當我們通過then讀取資料時,相當於為Promise設定了回撥函式
        1. 如果PromiseState變為fulfilled,則呼叫then的第一個回撥函式來返回資料
        2. 如果PromiseState變為rejected。則呼叫then的第二個回撥函式來返回資料
    const promise2 = new Promise((resolve, reject) => {
        resolve("哈哈")
    })
    
    // console.log(promise2)
    promise2.then(result => {
        console.log(result)
    }, reason => {
        console.log("出錯了")
    })
    
  4. catch()用法和then類似,但是隻需要一個回撥函式作為引數

    1. catch() 中的回撥只會在Promise被拒絕時才會呼叫

    2. catch() 相當於 then(null, reason=>{})

    3. catch() 就是一個專門處理Promise異常的方法

      promise2.catch(reason => {
          console.log(222222)
      })
      
  5. finally()

    1. 無論是正常儲存資料還是出現異常了,finally總會執行

    2. 但是finally的回撥函式中不會接收到資料

    3. finally()通常用來編寫一些無論成功與否都要執行的程式碼

      promise2.finally(()=>{
          console.log("沒有什麼能夠阻擋我執行的!")
      })