Promise 基础使用

Promise 是什么?

  1. 抽象表达:
    1. Promise 是一门新的技术(ES6 规范)
    2. Promise 是 JS 中进行异步编程的新解决方案
      备注:旧方案是单纯使用回调函数
  2. 具体表达:
    1. 从语法上来说: Promise 是一个构造函数
    2. 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

promise 的状态改变

  1. pending 变为 resolved/fullfilled
  2. pending 变为 rejected
    说明: 只有这 2 种, 且一个 promise 对象只能改变一次,无论变为成功还是失败, 都会有一个结果数据,成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

promise 的基本流程

promise 的基本使用

js 复制代码
        const btn = document.querySelector('#btn');
        //绑定单击事件
        btn.addEventListener('click', function(){
            //Promise 形式实现
            // resolve 解决  函数类型的数据
            // reject  拒绝  函数类型的数据
            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 对象的状态设置为 『失败』
                    }
                }, 1000);
            });
            //调用 then 方法
            // value 值
            // reason 理由
            p.then((value) => {
                alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 ' + value);
            }, (reason) => {
                alert('再接再厉, 您的号码为 ' + reason);
            });
        });

如何使用 Promise

  1. Promise 构造函数: Promise (excutor) {}
    1. executor 函数: 执行器 (resolve, reject) => {}
    2. resolve 函数: 内部定义成功时我们调用的函数 value => {}
    3. reject 函数: 内部定义失败时我们调用的函数 reason => {}

说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行

js 复制代码
        let p = new Promise((resolve, reject) => {
            console.log(111);
        });
        console.log(222); // 111 222
  1. Promise.prototype.then 方法: (onResolved, onRejected) => {}

    1. onResolved 函数: 成功的回调函数 (value) => {}

    2. onRejected 函数: 失败的回调函数 (reason) => {}

说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的 promise 对象

js 复制代码
        let p = new Promise((resolve, reject) => {
            // resolve(111);
            reject(222)
        });
        p.then((value) => {
            console.log(value) // 111
        },(reason) => {
            console.log(reason) // 222
        })
  1. Promise.prototype.catch 方法: (onRejected) => {}
    1. onRejected 函数: 失败的回调函数 (reason) => {} 说明: then()的语法糖, 相当于: then(undefined, onRejected)
js 复制代码
        let p = new Promise((resolve, reject) => {
            reject(222)
        });
        p.catch((reason)=>{
            console.log(reason) // 222
        })
  1. Promise.resolve 方法: (value) => {}

    1. value: 成功的数据或 promise 对象,说明: 返回一个成功/失败的 promise 对象
js 复制代码
        //如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
        let p1 = Promise.resolve(521);
        p1.then((res) => {
            console.log(res) // 521
        })
        
        //如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            resolve('OK');
        }));
        console.log(p2);
        p2.then(reason => {
            console.log(reason); // OK
        })
  1. Promise.reject 方法: (reason) => {}
    1. reason: 失败的原因,说明: 返回一个失败的 promise 对象
js 复制代码
        let p = Promise.reject(521);
        console.log(p) // Promise {<rejected>: 521}
js 复制代码
        let p3 = Promise.reject(new Promise((resolve, reject) => {
            resolve('OK');
        }));
        console.log(p3);
  1. Promise.all 方法: (promises) => {}

    1. promises: 包含 n 个 promise 的数组

说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败

js 复制代码
        let p1 = new Promise((resolve, reject) => {
            resolve('OK');
        })
        let p2 = Promise.resolve('Success');
        let p3 = Promise.resolve('Oh Yeah');
        const result = Promise.all([p1, p2, p3]);
        console.log(result);
js 复制代码
        let p1 = new Promise((resolve, reject) => {
            resolve('OK');
        })
        let p2 = Promise.reject('Error');
        let p3 = Promise.resolve('Oh Yeah');
        const result = Promise.all([p1, p2, p3]);
        console.log(result);
  1. Promise.race 方法: (promises) => {}
    1. promises: 包含 n 个 promise 的数组 说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态
js 复制代码
        let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        })
        let p2 = Promise.resolve('Success');
        let p3 = Promise.resolve('Oh Yeah');

        //调用
        const result = Promise.race([p1, p2, p3]);
        console.log(result);

promise 的几个关键问题

  1. 如何改变 promise 的状态?
    1. resolve(value): 如果当前是 pending 就会变为 resolved
    2. reject(reason): 如果当前是 pending 就会变为 rejected
    3. 抛出异常: 如果当前是 pending 就会变为 rejected
js 复制代码
        let p = new Promise((resolve, reject) => {
            //1. resolve 函数
            // resolve('ok'); // pending   => fulfilled (resolved)
            //2. reject 函数
            // reject("error");// pending  =>  rejected 
            //3. 抛出错误
            // throw '出问题了';
        });
  1. 一个 promise 指定多个成功/失败回调函数, 都会调用吗?

    当 promise 改变为对应状态时都会调用

js 复制代码
        let p = new Promise((resolve, reject) => {
            resolve('OK');
        });
        ///指定回调 - 1
        p.then(value => {
            console.log(value);
        });
        //指定回调 - 2
        p.then(value => {
            alert(value);
        });
  1. 改变 promise 状态和指定回调函数谁先谁后?

    1. 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
    2. 如何先改状态再指定回调?
      ① 在执行器中直接调用 resolve()/reject()
      ② 延迟更长时间才调用 then()
    3. 什么时候才能得到数据?
      ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
      ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
  2. promise.then()返回的新 promise 的结果状态由什么决定?

    1. 简单表达: 由 then()指定的回调函数执行的结果决定
    2. 详细表达:
      ① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
      ② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
      ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果\
js 复制代码
        let p = new Promise((resolve, reject) => {
            resolve('ok');
        });
        //执行 then 方法
        let result = p.then(value => {
            // console.log(value);
            //1. 抛出错误
            // throw '出了问题';
            //2. 返回结果是非 Promise 类型的对象
            // return 521;
            //3. 返回结果是 Promise 对象
            // return new Promise((resolve, reject) => {
            //     // resolve('success');
            //     reject('error');
            // });
        }, reason => {
            console.warn(reason);
        });
        console.log(result);
  1. promise 如何串连多个操作任务?
    1. promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用
    2. 通过 then 的链式调用串连多个同步/异步任务
js 复制代码
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        });
        p.then(value => {
            return new Promise((resolve, reject) => {
                resolve("success");
            });
        }).then(value => {
            console.log(value); // success
        }).then(value => {
            console.log(value); // undefined
        })
  1. promise 异常传透?

    1. 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,
    2. 前面任何操作出了异常, 都会传到最后失败的回调中处理
js 复制代码
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        });
        p.then(value => {
            throw '失败啦!';
        }).then(value => {
            console.log(222);
        }).then(value => {
            console.log(333);
        }).catch(reason => {
            console.warn(reason); // 失败啦
        });
  1. 中断 promise 链?
    1. 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
    2. 办法: 在回调函数中返回一个 pendding 状态的 promise 对象
js 复制代码
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        });
        p.then(value => {
            console.log(111);
            //有且只有一个方式
            return new Promise(() => {});
        }).then(value => {
            console.log(222);
        }).then(value => {
            console.log(333);
        }).catch(reason => {
            console.warn(reason);
        });

async 函数

  1. 函数的返回值是 promise 对象
  2. promise 对象的结果是由 async 函数执行的返回值决定。
  • 如果返回值是一个非 Promise 类型的数据,则结果是一个成功的 Promise
js 复制代码
async function fun() {
    return 111
}
let result = fun()
console.log(result) // Promise {<fulfilled>: 111}
  • 如果返回值是一个 Promise 类型的数据,则结果由返回的 Promise 决定
js 复制代码
async function fun() {
    return new Promise((resolve) => {resolve(123)})
}
let result = fun()
console.log(result)
js 复制代码
async function fun() {
    return new Promise((resolve,reject) => {reject(123)})
}
let result = fun()
console.log(result) 
  • 抛出异常
js 复制代码
async function fun() {
    throw '123'
}
let result = fun()
console.log(result) 

await 表达式

  1. await 右侧的表达式一般为 promise 对象,但也可以是其他值
  2. 如果表达式是 promise 对象,await 返回的是 promise 成功的值
  3. 如果表达式是其他值,直接将此值作为 await 的返回值
  4. 如果 awiat 的 promise 失败了,就会抛出异常,要通过 try...catch..捕获处理
js 复制代码
async function fun(){
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(111)
        }, 1000)
    })
    let result = await p
    console.log(result)
} 
fun() // 1秒后打印 111

async/await 结合

案例: 想要读取三个文件的内容,并组合在一起

这种写法好处是没有回调函数了。

相关推荐
脑袋大大的19 分钟前
JavaScript 性能优化实战:减少 DOM 操作引发的重排与重绘
开发语言·javascript·性能优化
速易达网络2 小时前
RuoYi、Vue CLI 和 uni-app 结合构建跨端全家桶方案
javascript·vue.js·低代码
耶啵奶膘2 小时前
uniapp+firstUI——上传视频组件fui-upload-video
前端·javascript·uni-app
JoJo_Way2 小时前
LeetCode三数之和-js题解
javascript·算法·leetcode
视频砖家2 小时前
移动端Html5播放器按钮变小的问题解决方法
前端·javascript·viewport功能
lyj1689973 小时前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
小白变怪兽4 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头4 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
墨菲安全5 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒