ES6——Promise

时间:2022-12-09 19:04:54

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 })