滑板遊戲《Session》將於9月22日正式發售 離開搶先體驗
Promise
1.Promise的前置知識
-
程序(廠房)
- 程式的執行環境
-
執行緒(工人)
- 執行緒是實際進行運算的東西
-
同步
- 通常情況程式碼都是自上向下一行一行執行的
- 前邊的程式碼不執行後邊的內碼表不會執行
- 同步的程式碼執行會出現阻塞的情況
- 一行程式碼執行慢會影響到整個程式的執行
-
解決同步的問題:
-
java python
- 通過多執行緒來解決,但是一般消耗資源比較多
-
node.js
-
通過非同步方式來解決
我們可以這麼理解:客人就好比我們請求的資料,服務員就好比客戶端,廚師就好比伺服器,我們現在客人點菜,服務員接收到菜的名稱資訊,給廚師說,廚師開始做,廚師在做的時候,客人一直等,不能幹其他的事情,這就是同步,只能幹一件事,我們現在利用非同步的方式,可以讓客人在課桌上等著菜來,也不影響服務員接收下一個客人的點菜,這樣就可以很好的處理同步所帶來的堵塞問題
-
-
-
非同步
-
一段程式碼的執行不會影響到其他的程式
-
非同步的問題:
- 非同步的程式碼無法通過
return
來設定返回值
- 非同步的程式碼無法通過
-
特點:
-
不會阻塞其他程式碼的執行
-
需要通過回撥函式來返回結果
function sum(a, b, cb) { setTimeout(() => { cb(a + b) //呼叫箭頭函式,把結果作為回撥函式的引數 }, 1000) } sum(123, 456, (result)=>{ console.log(result) })
-
-
基於回撥函式的非同步帶來的問題
-
程式碼的可讀性差
-
可除錯性差(造成回撥地獄)
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可以用來儲存非同步呼叫的資料
- Promise是一個可以用來儲存資料的物件
-
2.Promise介紹
非同步呼叫必須要通過回撥函式來返回資料,當我們進行一些複雜的呼叫時,會出現回撥地獄
問題:
非同步必須通過回撥函式來返回結果,回撥函式增加就不容易處理
- Promise
- Promise可以幫助我們解決非同步中的回撥函式的問題
- Promise就是一個用來儲存資料的容器
- 它擁有著一套特殊的儲存資料的方式
- 這個方式使得它裡面可以儲存非同步呼叫的結果
-
建立Promise
-
建立Promise時,建構函式中需要一個函式作為引數
-
Promise建構函式的回撥函式,它會在建立Promise時呼叫,呼叫時會有兩個引數傳遞進去
const promise = new Promise((resolve, reject)=>{ // resolve 和 reject 是兩個函式,通過這兩個函式可以向Promise中儲存資料 // resolve 在執行正常的時候儲存資料, reject 是在執行錯誤的時候儲存資料 resolve('我是正常執行的時候呼叫的') reject('我是錯誤執行的時候呼叫的') //通過函式來訪問Promise中新增資料,好處就是可以用來新增非同步呼叫的資料 setTimeout(()=>{ resolve('非同步中呼叫資料') },2000) throw new Error('出錯了,呼叫的是reject') })
-
-
從Promise中讀取資料
-
可以通過Promise的例項方法
then
來讀取Promise中儲存的資料 -
then需要兩個回撥作為引數,回撥函式來獲取Promise中的資料
-
通過resolve儲存的資料,會呼叫第一函式返回,可以在第一個函式中編寫處理資料的程式碼
-
通過reject儲存資料或者出現異常時,會呼叫第二個函式返回,可以在第二個函式中編寫處理異常的程式碼
promise.then((result)=>{ console.log('1',result) },(reson)=>{ console.log('2',reason) })
-
-
-
Promise中維護了兩個隱藏屬性:
- PromiseResult
- 用來儲存資料
- PromiseState
- 記錄Promise的狀態(三種狀態)
-
pending
(進行中) -
fulfilled
(完成)通過resolve儲存資料時 -
rejected
(拒絕,出錯了)出錯了或通過reject儲存資料時
-
- state只能修改一次,修改以後永遠不會在變
- 記錄Promise的狀態(三種狀態)
- 流程:
- 當Promise建立時,PromiseState初始值為pending
- 當通過resolve儲存資料時 PromiseState 變為fulfilled(完成)
- PromiseResult變為儲存的資料
- 當通過reject儲存資料或出錯時 Promise 變為rejected(拒絕)
- PromiseResult變為儲存的資料 或 異常物件
- 當通過resolve儲存資料時 PromiseState 變為fulfilled(完成)
- 當我們通過then讀取資料時,相當於為Promise設定了回撥函式
- 如果PromiseState變為fulfilled,則呼叫then的第一個回撥函式來返回資料
- 如果PromiseState變為rejected。則呼叫then的第二個回撥函式來返回資料
- 當Promise建立時,PromiseState初始值為pending
const promise2 = new Promise((resolve, reject) => { resolve("哈哈") }) // console.log(promise2) promise2.then(result => { console.log(result) }, reason => { console.log("出錯了") })
- PromiseResult
-
catch()
用法和then類似,但是隻需要一個回撥函式作為引數-
catch() 中的回撥只會在Promise被拒絕時才會呼叫
-
catch() 相當於 then(null, reason=>{})
-
catch() 就是一個專門處理Promise異常的方法
promise2.catch(reason => { console.log(222222) })
-
-
finally()
-
無論是正常儲存資料還是出現異常了,finally總會執行
-
但是finally的回撥函式中不會接收到資料
-
finally()通常用來編寫一些無論成功與否都要執行的程式碼
promise2.finally(()=>{ console.log("沒有什麼能夠阻擋我執行的!") })
-