ES6——Promise

2022-12-09 21:00:47

一、ES6——Promise

1.1 Promise介紹與基本使用

  PromiseES6引入的非同步程式設計的新解決方案。語法上promise是一個建構函式,用來封裝非同步操作並獲取其成功或失敗的結果。

1.1.1範例化Promise物件

  • 範例化的promise物件的引數會接收一個函數型別的值

  • Promise物件的三個狀態:初始化、成功、失敗
 1 //函數有兩個形參resolve和reject
 2 const p = new Promise(function(resolve,reject){
 3     //函數內部封裝一個非同步操作
 4     setTimeout(function(){
 5         //獲取資料
 6         let data = '資料庫中的使用者資料';
 7         //得到資料後,可以呼叫 resolve 和 reject 函數來改變promise物件的狀態
 8         //resolve
 9         resolve(data);//Promise物件狀態改變:成功
10         
11         let err = '資料讀取失敗';
12         reject(err);//Promise物件狀態改變:失敗
13     },1000)
14 });
15 
16 //呼叫promise物件的then方法
17 //then接收兩個引數,倆引數都是函數型別的值
18 p.then(function(value){
19     //成功
20     console.log(value);
21 },function(reason){
22     //失敗
23     console.log(reason);
24 })

二、Promise封裝讀取檔案

 1 //引入fs模組
 2 const fs = require("fs");
 3 //Promise封裝
 4 const p = new Promise(function(resolve,reject){
 5     fs.readFile("./待讀取檔案1.md",(err,data)=>{
 6         //判斷如果失敗
 7         if(err) reject(err);
 8         //如果成功
 9         resolve(data);
10     });
11 });
12 
13 p.then(function(value){
14     console.log(value.toString());//結果是buffer型別,使用toStringjin'xing
15 },function(reason){
16     console.log("讀取失敗");
17 })

三、 Promise封裝AJAX請求

 1 //使用原生Ajax向一個url傳送請求
 2 //介面地址:http://api.apiopen.top/getJoke
 3 
 4 const p = new Promise((resolve,reject)=>{
 5     //1.建立物件
 6     const xhr = new XMLHttpRequest();
 7     //2.初始化
 8     xhr.open("GET","http://api.apiopen.top/getJoke");
 9     //3.傳送
10     xhr.send();
11     //4.繫結事件,處理響應結果
12     xhr.onreadystatechange = function(){
13         //判斷
14         if(xhr.readyState === 4){
15             //判斷響應狀態碼 200-299 成功
16             if(xhr.status >= 200 && xhr.state < 300){
17                 //表示成功
18                 resolve(xhr.response);
19             } else{
20                 //失敗
21                 reject(xhr.status);
22             }
23         }
24     }
25 })
26 //指定回撥,將回撥單拎出來
27 p.then(function(value){
28     console.log(value);
29 },function(reason){
30     console.error(reason);
31 })

四、Promise.prototype.then方法

  then方法的返回結果是 Promise 物件,物件的狀態由回撥函數的執行結果決定。

  1. 如果函調函數中返回的結果是非promise型別的屬性,狀態為成功,返回值為物件成功的值;

  2. promise 物件,返回的這個 promise 物件決定了最外層 promise 的狀態和結果;

  3. 丟擲錯誤,最外層 Promise 物件狀態為失敗,並且返回丟擲的值。
 1 //建立Promise物件
 2 const p = new Promise((resolve,reject)=>{
 3     setTimeout(()=>{
 4         resolve('使用者資料');
 5     },1000)
 6 });
 7 
 8 //呼叫then方法
 9 const result = p.then(value=>{
10     consolve.log(value);
11     //1.非 promise 型別的屬性
12     return '成功';
13     //2.是 promise 物件,返回的這個 promise 物件決定了最外層 promise 的狀態和結果
14     return new Promise((resolve,reject)=>{
15         resolve('ok');
16     });
17     //3.丟擲錯誤
18     throw new Error('出錯啦');
19 },reason=>{
20     consolve.warn(reason);
21 });
22 console.log(result);

  鏈式呼叫,then方法可以進行鏈式呼叫。

1 p.then(value=>{
2     
3 }).then(value=>{
4     
5 },reason=>{
6     
7 });

五、Promise練習

5.1 讀取多個檔案

 1 //引入fs模組
 2 const fs = require("fs");
 3 使用 Promsie 實現
 4 const p  = new Promise((resolve,reject)=>{
 5     fs.readFile("./res/待讀取檔案1.md",(err,data)=>{
 6         resolve(data);
 7     });
 8 });
 9 
10 
11 //value是第一個檔案的值
12 p.then((value)=>{
13     console.log(value.toString());//將結果字串轉換
14     //為了防止產生回撥地獄,可以返回一個Promise物件
15     return new Promise((resolve,resolve)={
16         fs.readFile("./res/待讀取檔案2.md",(err,data)=>{
17             //這裡data是第二個檔案的值
18             resolve([value,data]);
19         });
20     })
21 }).then(value =>{
22     //此時的value為第一個檔案結果和第二個檔案結果的集合(陣列)
23     return new Promise((resolve,resolve)={
24         fs.readFile("./res/待讀取檔案3.md",(err,data)=>{
25             //這裡data是第三個檔案的值
26             //壓入
27             value.push(data);
28             resolve(value);
29         });
30     })
31 }).then(value =>{
32     //此時的value為取出來的三個檔案的值
33     console.log(value.join('\r\n'));//結果為陣列,所以用換行進行拼接
34 });

六、Promise 物件catch方法

  用來指定Promise失敗的回撥。

 1 const p = new Promise((resolve,reject)=>{
 2     setTimeout(()=>{
 3         //設定p物件的狀態為失敗,並設定失敗的值
 4         reject("出錯啦");
 5     },1000)
 6 });
 7 
 8 //方法一
 9 //p.then(function(reason){
10     //console.error(reason);
11 //})
12 
13 //方法二(算是then的一個語法糖)
14 p.catch(function(reason){
15     console.warn(reason);
16 })