Promise(一) 介绍及基本使用+API

目录

1.Promise 的理解和使用

1.1. Promise 是什么?

1.1.1. 理解

1.2. 为什么要用 Promise?

1.2.1. 指定回调函数的方式更加灵活

1.2.2. 支持链式调用, 可以解决回调地狱问题  

         1.3 promise初体验

1.4 Promise实践练习——fs读取文件

1.5 Promise实践练习——Ajax请求

1.6 Promise实践——封装fs读取文件操作

1.7 util.promisify 方法进行Promise风格转化

1.8 Promise封装AJAX操作

1.9 Promise对象属性状态介绍

1.10 promise对象结果值属性介绍

1.11 promise 的基本流程:

2. Promise相关的API

 2.1 构造函数-then-catch

 2.2 Promise.resolve方法

 2.3  Promise.reject方法

 2.4  Promise.all方法

 2.5  Promise.race方法


1.Promise 的理解和使用

1.1. Promise 是什么?

1.1.1. 理解

 构造函数进行对象的实例化 

1.2. 为什么要用 Promise?

1.2.1. 指定回调函数的方式更加灵活

之前在进行异步任务之前必须把回调函数准备好

1.2.2. 支持链式调用, 可以解决回调地狱问题  

 回调地狱示例:

 1.3 promise初体验

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>基本使用</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <h2 class="page-header">Promise 初体验</h2>
        <button class="btn btn-primary" id="btn">点击抽奖</button>
    </div>
    <script>
        //生成随机数
        function rand(m,n){
            return Math.ceil(Math.random() * (n-m+1)) + m-1;
        }
        /**
            点击按钮,  1s 后显示是否中奖(30%概率中奖)
                若中奖弹出    恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券
                若未中奖弹出  再接再厉
        */
        //获取元素对象
        const btn = document.querySelector('#btn');
        //绑定单击事件
        btn.addEventListener('click', function(){
            //定时器
            // setTimeout(() => {
            //     //30%  1-100  1 2 30
            //     //获取从1 - 100的一个随机数
            //     let n = rand(1, 100);
            //     //判断
            //     if(n <= 30){
            //         alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券');
            //     }else{
            //         alert('再接再厉');
            //     }
            // }, 1000);1s钟

            //Promise 形式实现
            //Promise在实例化时需要接受一个参数,这个参数是函数类型的值,resolve, reject是两个形参
            // resolve 解决  函数类型的数据
            // reject  拒绝  函数类型的数据
            // 异步任务成功的时候调resolve,失败的时候调reject
            //promise可以包裹异步操作,然后把异步操作代码setTimeout放进来
            const p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    //30%  1-100  1 2 30
                    //获取从1 - 100的一个随机数
                    let n = rand(1, 100);
                    //判断
                    if(n <= 30){
                        resolve(n); // 将 promise 对象的状态设置为 『成功』
                    }else{
                        reject(n); // 将 promise 对象的状态设置为 『失败』
                    }
                    //把n当作结果值传递给resolve,reject的函数传给下面的value和reason
                }, 1000);
            });

            console.log(p);
            //调用 then 方法,指定成功或者失败时的回调,处理成功和失败的结果
            // value 值  第一个参数是对象成功后的回调
            // reason 理由   第二个参数是对象失败后的回调
            p.then((value) => {
                alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 ' + value);
            }, (reason) => {
                alert('再接再厉, 您的号码为 ' + reason);
            });

        });

    </script>
</body>

</html>

 1.4 Promise实践练习——fs读取文件

//fs可以对计算机硬盘进行读写操作,
//本次读取resource底下content.txt
//首先引进fs模块
const fs = require('fs');

//回调函数(无promise的形式) 形式  err为出现错误时,data是我们要的参数,(err, data) => {是回调函数
// fs.readFile('./resource/content.txt', (err, data) => {
//     // 如果出错 则抛出错误
//     if(err)  throw err;
//     //输出文件内容
//     console.log(data.toString());
//.toString()转成字符串
// });

//Promise 1.形式封装,首先创建promise对象,里面放一个异步任务
let p = new Promise((resolve , reject) => {
    fs.readFile('./resource/content.txt', (err, data) => {
        //如果出错
        if(err) reject(err);
        //如果成功
        resolve(data);
    });
});

//2.调用 then ,对结果进行处理
p.then(value=>{
    console.log(value.toString());
}, reason=>{
    console.log(reason);
});

 1.5 Promise实践练习——Ajax请求

 Promise步骤:   都一个路数,创建promise对象,把异步任务代码(就相当于原来的回调函数)放进去,成功时调resolve,失败调reject,顺便把成功和失败结果传进去,然后在then方法中指定成功和失败的回调,对结果进行处理

注意:实现异步编程:回调函数和Promise都行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise 封装 AJAX</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <!-- 案例点击按钮发送Ajax请求,给下面的接口地址发 -->
    <div class="container">
        <h2 class="page-header">Promise 封装 AJAX 操作</h2>
        <button class="btn btn-primary" id="btn">点击发送 AJAX请求</button>
    </div>
    <script>
        //接口地址 https://api.apiopen.top/getJoke
        //获取元素对象,把按钮放进来
        const btn = document.querySelector('#btn');

        btn.addEventListener('click', function(){
            //(2)创建 Promise实现异步
            const p = new Promise((resolve, reject) => {
               //(1)回调函数实现异步:Ajax四部操作 //1.创建对象
                const xhr = new XMLHttpRequest();
                //2. 初始化,给接口发get请求
                xhr.open('GET', 'https://api.apiopen.top/getJoke');
                //3. 发送
                xhr.send();
                //4. 绑定事件处理响应结果
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        //判断响应状态码 2xx开头是成功   
                        if(xhr.status >= 200 && xhr.status < 300){
                            //控制台输出响应体(xhr.response)
                            // 使用回调函数就都用console.log打印
                            resolve(xhr.response);
                        }else{
                            //控制台输出响应状态码
                            reject(xhr.status);
                        }
                    }
                }
            });
            //调用then方法
            p.then(value=>{
                console.log(value);
            }, reason=>{
                console.warn(reason);
            });
        });
    </script>
</body>
</html>

1.6 Promise实践——封装fs读取文件操作

/**使用Promise的方式对读取文件进行了一个函数封装
 * 封装一个函数 mineReadFile 作用是读取文件内容
//  * 必须要在Node.js环境下运行,不能在浏览器中引入该文件
 * 函数接受参数:  path  文件路径,想读取的文件把路径传递给mineReadFile
 * 返回:  promise 对象,,成功结果为文件内容,失败结果为错误对象
 */
function mineReadFile(path){
    //返回:  promise 对象
    return new Promise((resolve, reject) => {
        //读取文件第一个参数为路径,第二个参数是回调
        require('fs').readFile(path, (err, data) =>{
            //判断
            if(err) reject(err);
            //成功
            resolve(data);
        });
    });
}
// 调用函数读取,因为mineReadFile函数返回结果是一个Promise对象,所以可以直接调then
mineReadFile('./resource/content.txt')
.then(value=>{
    //输出文件内容
    console.log(value.toString());
}, reason=>{
    console.log(reason);
});

1.7 util.promisify 方法进行Promise风格转化

/**promisify 方法属于util模块,错误优先回调,把这个方法给他,返回一个Promise版本
 * util.promisify 方法
 */
// 以读取文件为例演示
//引入 util 模块
const util = require('util');
//引入 fs 模块
const fs = require('fs');
//返回一个新的函数,返回新函数的结果mineReadFile是一个promise对象
//util.promisify接受一个错误优先的方法
let mineReadFile = util.promisify(fs.readFile);

mineReadFile('./resource/content.txt').then(value=>{
    console.log(value.toString());
});
//运行的时候在vscode里面不进浏览器,在底下的控制台输入Node 5-util.promisify 方法.js显示结果
//以后使用Promise,不需要每个方法都进行手动封装,而是借助util.promisify方法将原来回调函数的风格的方法转成mineReadFile-promise风格的函数

1.8 Promise封装AJAX操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise封装AJAX操作</title>
</head>
<body>
    <script>
        /**
         * 封装一个函数 sendAJAX 发送 GET AJAX 请求
         * 参数   URL
         * 返回结果 Promise 对象
         */
        function sendAJAX(url){
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.responseType = 'json';
                //给url发
                xhr.open("GET", url);
                xhr.send();
                //处理结果
                xhr.onreadystatechange = function(){
                    //为4是所有结果都返回的状态
                    if(xhr.readyState === 4){
                        //判断成功
                        if(xhr.status >= 200 && xhr.status < 300){
                            //成功的结果
                            resolve(xhr.response);
                        }else{
                            reject(xhr.status);
                        }
                    }
                }
            });
        }
    
        sendAJAX('https://api.apiopen.top/getJok')
        .then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        });
    </script>
</body>
</html>

1.9 Promise对象属性状态介绍

Promise实例对象当中的一个属性叫promiseState

 

1.10 promise对象结果值属性介绍

 resolve/reject可以修改这个值,then方法回调中才能把这个值取出来进行相关操作,不管成功失败,最终结果resolve/reject都保存在PromiseResult中

 1.11 promise 的基本流程:

2. Promise相关的API

2.1这三个方法都属于实例化对象,剩下的方法都是属于Promise函数对象的

2.1 构造函数-then-catch

 new promise来实例化对象,new的时候实例化要接收一个参数excutor

 

 

 catch只能指定失败的回调,不能指定成功的回调

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise API</title>
</head>
<body>
    <script>
        //
        let p = new Promise((resolve, reject) => {
            // ** 同步调用
            // console.log(111);
            //修改 promise 对象的状态
            reject('error');
        });
//111和222是同步调用的
        // console.log(222);

        //执行 catch 方法指定失败的回调
        p.catch(reason => {
            console.log(reason);
        });
    </script>
</body>
</html>

 2.2 Promise.resolve方法

Promise.resolve方法属于Promise这个函数对象的,不属于实例对象

作用:快速得到promise对象,而且还能封装一个值,将这个值转化为promise对象

    <script>
        let p1 = Promise.resolve(521);
        //p1如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
        //p2如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果,成功或失败
        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            // resolve('OK');
            reject('Error');
        }));
        // console.log(p2);上面如果是resolve('OK');打印出来的结果也是成功的promise,
        //上面传进来成功的结果为ok,外层p2这和结果也是ok
        //如果上面是失败的promise,下面就要有对应的回调来对失败结果进行处理,不能console.log
        p2.catch(reason => {
            console.log(reason);
        })
    </script>

  2.3  Promise.reject方法

 和resolve一样,这个方法属于Promise这个函数对象的,不属于实例对象

作用:快速返回一个失败的promise对象,可以将一个值快速转换成promise对象,只不过这个值是失败的,它接收一个参数,返回的结果一直是失败的promise对象

    <script>
        //返回的结果永远都是失败的,传入什么,失败的结果是什么
        // let p = Promise.reject(521);
        //无论你传入什么样的数值,返回结果都是失败的
        // let p2 = Promise.reject('iloveyou');
        let p3 = Promise.reject(new Promise((resolve, reject) => {
            resolve('OK');
        }));
        //即便传入的是一个成功的promise对象,他的结果也是失败
        //(状态是失败,而失败的结果是你传进来的这个成功的promise对象)
        console.log(p3);
    </script>

  2.4  Promise.all方法

它接受的参数一般为 promise 组成的数组,这个参数结构里面每一个都是一个promise对象

返回结果也是一个promise对象

他的状态由数组中所有promise对象决定数组中的promise对象都成功,则返回的这个promise对象才成功,有一个失败,返回结果就是失败的promise对象。

且成功的结果是数组中所有promise对象成功结果组成的一个数组;失败的结果是在这个数组中失败的那个promise对象的结果

    <script>
        let p1 = new Promise((resolve, reject) => {
            resolve('OK');
        })
        // let p2 = Promise.resolve('Success');
        let p2 = Promise.reject('Error');
        let p3 = Promise.resolve('Oh Yeah');
        
        //原来的//p2,三个都成功,all方法的返回结果是成功的promise,
           //成功的结果是p1,p2,p3三个promise对象的成功结果组成的一个数组
        //改完p2Promise.reject('Error');这样了就不成功了,返回失败结果Error
        const result = Promise.all([p1, p2, p3]);

        console.log(result);
    </script>

  2.5  Promise.race方法

  它接受的参数一般为 promise 组成的数组,返回结果也是一个promise对象,与all有点像

它的结果状态:由第一个改变状态的promise对象决定,它成功race就成功,它失败race就失败,像Promise中在赛跑,谁先该改变状态,谁就决定race方法的返回结果

    <script>
        let p1 = new Promise((resolve, reject) => {
            //设个异步任务
            setTimeout(() => {
                resolve('OK');
            }, 1000);//1s钟以后才改变状态
        })
        let p2 = Promise.resolve('Success');
        let p3 = Promise.resolve('Oh Yeah');
        //没有异步任务的时候p1先改变,设了按照顺序就是p2
        //调用
        const result = Promise.race([p1, p2, p3]);

        console.log(result);
    </script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值