Promise第一篇:基本使用方法和串联
目錄
1.基本使用
2.Promise的串聯
1.基本使用
首先清楚promise的過程:事件從unsettled未解決階段(pending狀態)開始發展到settled已解決階段(resolved和rejected狀態),Promise對象可以傳resolve與reject兩個函數,其中resolve函數將Promise推向resolved階段,reject函數將Promise推向rejected階段,且兩者均只可傳一個參數,表示推向狀態的數據,下面給個圖理解一下
?注冊thenable函數:當Promise是resolved狀態時,執行thenable函數,注冊格式如【例1-1】
?注冊catchable函數:當Promise是rejected狀態時,執行catchable函數,注冊格式如【例1-1】
【例1-1】pro.then可以只添加thenable函數,pro.catch可以單獨添加catchable函數
方法一
const pro = new Promise((resolve, reject) => {}) pro.then(data => { //data是狀態數據}) pro.catch(err => { //err是狀態數據})方法二
const pro = new Promise((resolve, reject) => {}) pro.then(data => {}, err => {})【注】
1)如果當前是未解決階段,thenable函數和catchable函數會加入到作業隊列,等待狀態到達后執行
2)未解決階段的處理函數是同步的,會立即執行,thenable和catchable函數是異步的,就算是立即執行,也會加入到事件隊列中等待執行,并且,加入的是微隊列【例1-2】
4)在未解決階段的處理函數中,如果發生未捕獲的錯誤,會將狀態推向rejected,并會被catchable捕獲【例1-3】
5)一旦狀態推向了已解決階段,無法再對狀態做任何更改
6)Promise并沒有消除回調,只是讓回調變得可控
【例1-2】
const pro = new Promise((resolve, reject) => {console.log('未解決階段');setTimeout(() => {console.log('計時器進宏隊列')}, 0);resolve(123); }) pro.then(data => {console.log(data); }) console.log('執行棧不為空');【結果】首先事件是pending狀態,執行第二行代碼,打印“未解決階段”;之后定時器線程監控到有計時器事件,計時器事件進入宏隊列,等待執行,然后狀態到達resolved,調用thenable函數,放進微隊列,但是由于此時的執行棧并不是空棧,還有log事件,因此先執行第十一行代碼,打印“執行棧不為空”,之后執行棧為空,優先執行微隊列中的thenable函數,打印data“123”,再執行宏隊列,打印“計時器進宏隊列”,結果圖1-2所示
圖1-2【例1-3】
const pro = new Promise((resolve,reject)=>{throw new Error('rejected'); }) pro.then(data =>{console.log(data); }) pro.catch(err=>{console.log(err); })【結果】
圖1-32.Promise的串聯
當后續的Promise需要用到之前的Promise的處理結果時,需要Promise的串聯。在Promise對象中,無論then方法還是catch方法,它們都具有返回值,返回的是一個全新的Promise對象【例2-1】
【注】它的狀態滿足下列規則
- 如果當前的Promise是未解決的,得到的新的Promise是掛起狀態【例2-2】
- 后續的Promise一定會等到前面的Promise有了后續處理結果后才會變成已解決狀態【例2-2】
- 如果當前的Promise是已解決的,會運行相應的后續處理函數,并將后續處理函數的結果(返回值)作為resolved的狀態數據,應用帶新的Promise中,如果后續處理函數發生錯誤,則把返回值作為rejected狀態數據,應用到新的Promise中【例2-3】
【注】若前面的Promise的后續處理,返回的是Promise,則返回的新的Promise狀態和后續處理返回的Promise狀態保持一致【例2-4】
【例2-1】
// then/catch的返回結果是一個新的Promise const pro = new Promise((resolve, reject) => {if (Math.random() > 0.5) {resolve(1);} else {reject(2);} }) const pro1 = pro.then(result => {return result * 2; }, err => {return err * 2 }) console.log('pro:',pro); console.log('pro1:',pro1);【結果】
圖2-1【例2-2】
//當前Promise為解決狀態,則新的得到的Promise是掛起狀態 const pro = new Promise((resolve, reject) => {setTimeout(() => {resolve(123)}, 500); }) const pro1 = pro.then(result => {console.log(result); }) console.log(pro); console.log(pro1);【結果】
圖2-2-1等pro的后續處理函數執行以后,pro1的掛起狀態變為resolved狀態,
圖2-2-2【例2-3】***重點***
const pro = new Promise((resolve, reject) => { if (Math.random() > 0.5) {//運行pro的thenable函數resolve(1); } else {//運行pro的catchable函數reject(2); } }) const pro1 = pro.then(result => { //pro的thenable函數 if (Math.random() > 0.5) {console.log('狀況1')//執行pro1的thenable函數,且狀態數據來自pro的thenable函數,打印 1 * 2 * 2 = 4return result * 2; } else {console.log('狀況2')//執行pro1的catchable函數,且狀態數據來自pro的thenable函數,打印 1 * 3 * 3 = 9throw result * 3; } }, err => { //pro的catchable的函數 if (Math.random() > 0.5) {console.log('狀況3')//執行pro1的thenable函數,且狀態數據來自pro1的catchable函數,打印 2*2*2 = 8return err * 2; } else {console.log('狀況4')//執行pro1的catchable函數,且狀態數據來自pro1的catchable函數,打印 2 * 3 * 3 = 18throw err * 3 } }) //前者為pro1的thenable函數,后者為pro1的catchable函數 pro1.then(result => console.log(result * 2), err => console.log(err * 3))【結果】上述4種狀態,分別打印4,9,8,18,感覺代碼分析的很清楚了,這里就不貼圖了,小伙伴可以自己試試
【例2-4】
const pro1 = new Promise((resolve, reject) => {resolve(1); }) const pro2 = new Promise((resolve, reject) => {setTimeout(() => {resolve(2)}, 2000); }) pro1.then(result => {console.log('結果出來了,得到的是一個Promise');return pro2; }).then(result => {console.log(result); }).then(result => {console.log(result); })【結果】第一行立即打印,第二行和第三行隔2000毫秒打印,并且數據和狀態是拿pro2的狀態和數據,第3行打印undefined,是因為前一個Promise沒有返回值
圖2-4?
總結
以上是生活随笔為你收集整理的Promise第一篇:基本使用方法和串联的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习Promise之前你必须理解的知识点
- 下一篇: Promise第二篇:你需要记着的API