目錄
一、Promise是什么
二、回調地獄
三、Promise解決回調地獄的原理
四、promaise實例
一、Promise是什么
1、主要用于異步計算
2、可以將異步操作隊列化,按照期望的順序執行,返回符合預期的結果
4、可以在對象之間傳遞和操作promise,幫助我們處理隊列
二、回調地獄
當一個回調函數嵌套一個回調函數的時候,就會出現一個嵌套結構,當嵌套的多了就會出現回調地獄的情況, 比如我們發送三個 ajax 請求,第一個正常發送,第二個請求需要第一個請求的結果中的某一個值作為參數,第三個請求需要第二個請求的結果中的某一個值作為參數,回調地獄,其實就是回調函數嵌套過多導致的。
ajax({url: '我是第一個請求',success (res) {// 現在發送第二個請求ajax({url: '我是第二個請求',data: { a: res.a, b: res.b },success (res2) {// 進行第三個請求ajax({url: '我是第三個請求',data: { a: res2.a, b: res2.b },success (res3) {console.log(res3) ;// ...}})}})}})
三、Promise解決回調地獄的原理
下面就帶大家創建一個Promise對象
let p1 = new Promise(function (resolve, reject) {// 此處執行異步的代碼setTimeout(()=>{// 我們可以根據自己的標準在異步任務完成的時候// 選擇是執行失敗的回調函數還是成功的回調函數// 第一個形參resolve 表示成功的回調resolve('300')// 第二個形參reject 表示失敗的回調},3000)
})// 定義當p1這個promise對象變成成功狀態的時候要執行的回調函數
p1.then((data)=>{console.log("我是成功的時候執行的函數")console.log("我執行的時候你給我傳入的參數",data)
})// 定義當p1這個promise對象變成失敗狀態的時候要執行的回調函數
p1.catch((err)=>{console.log("我是失敗的時候執行的函數")console.log("我執行的時候你給我傳入的參數",err)
})
resolve作用是,將Promise對象的狀態從“未完成”變為“成功”(即從 pending 變為 resolved),在異步操作成功時調用,并將異步操作的結果,作為參數傳遞出去;
reject作用是,將Promise對象的狀態從“未完成”變為“失敗”(即從 pending 變為 rejected),在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去。
Promise是一個對象,這個對象有三個狀態:
待定(pending):初始狀態,既沒有成功,也沒有失敗,表示異步任務正在進行中
成功(fulfilled):異步任務執行完畢,變成成功狀態
失敗(rejected):異步任務執行完畢,變成失敗狀態
當promise狀態發生改變,就會觸發then()里的響應函數處理后續步驟;
promise狀態一經改變,不會再變
Promise對象的狀態改變,只有兩種可能:
從pending變為fulfilled
從pending變為rejected
Promise對象這樣就創建好了,下面來解決ajax回調地獄問題。
四、promaise實例
傳統寫法
const fs = require("fs")
fs.readFile("./one.txt", (err, data1) => {fs.readFile("./two.txt", (err, data2) => {fs.readFile("./three.txt", (err, data3) => {console.log(data1 + "\n" + data2 + "\n" + data3)})})
})
Promise寫法
const fs = require("fs")const p = new Promise((resolve, reject) => {fs.readFile("./one.txt", (err, data) => {resolve(data)})
})
p.then(value => {return new Promise((resolve, reject) => {fs.readFile("./two.txt", (err, data) => {resolve([value, data])})})
}).then(value => {return new Promise((resolve, reject) => {fs.readFile("./three.txt", (err, data) => {value.push(data)resolve(value)})})
}).then(value => {let str = value.join("\n")console.log(str)
})