文章目录
一、Promise介绍与基本使用1-1.初体验之promise封装ajax请求1-2.Promise对象状态属性PromiseState的值有三个1-3.Promise对象状态属性PromiseResults 二、Promise API2-1.Promise构造函数Promise(excutor){}2-2.Promise.prototype.then 方式:(onResolved,onRenjected) => {}2-3.Promise.prototype.catch 方式:(onRejected) => {}2-4.Promise.resolve(参数) => {}2-5.Promise.reject(参数) => {}2-6.Promise.all(数组) => {}2-7.Promise.race(数组) => {} 三、Promise关键问题3-1.如何修改对象的状态3-2.能否执行多个回调3-3.改变promise状态和指定回调函数谁先谁后3-4.promise.then方法返回结果由什么决定3-5.Promise如何让串联多个操作任务3-6.异常穿透3-7.中断promise链 四、Promise自定义封装五、async与await5-1.async表达式5-2.await表达式5-3.async和await实战结合
一、Promise介绍与基本使用
抽象表达
 Promise是一门新的技术
 Promise是JS中进行异步编程的新解决方案
 备注:旧方案是单纯使用回调函数
具体表达
 从语法上来说Promise是一个构造函数
 从功能上来说Promise对象用来封装一个异步操作并可以获取其成功失败的结果值
基本使用
 fs文件操作
 定时器
 ajax请求
 操作mysql
作用
 解决回调地狱
1-1.初体验之promise封装ajax请求
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><body>    <script>        function sendAjax(url){            // return一个promise对象            // resolve ==> 解决            // reject ==> 拒绝            return new Promise((resolve,reject) =>{                const xhr = new XMLHttpRequest();                xhr.responseType = 'json';                xhr.open('get',url);                xhr.send();                // 处理结果                xhr.onreadystatechange = function(){                    if(xhr.readyState === 4){                        // 判断成功                        if(xhr.status >= 200 && xhr.status < 300){                            // 成功的结果                            resolve(xhr.response)                        }else{                            reject(xhr.status)                        }                    }                }            })        }        sendAjax('请求地址')    </script></body></html>1-2.Promise对象状态属性PromiseState的值有三个
pending 待定的状态resolve 成功的状态reject 失败的状态1-3.Promise对象状态属性PromiseResults
PromiseResults对象存储的是成功或者失败的结果
 可以通过resolve和reject修改其结果
二、Promise API
2-1.Promise构造函数Promise(excutor){}
1. excutor函数:执行器2. resolve函数:内部定义成功时我们调用的函数 valule => {}3. reject函数:内部定义失败时我们调用的函数 reason => {}4. 说明:executor会在Promise内部立即同步调用,异步操作在执行器中执行2-2.Promise.prototype.then 方式:(onResolved,onRenjected) => {}
 1. onResolved函数:成功的回调函数 (value) =>{} 2. onRejected函数:失败的回调函数 (reason) =>{} 3. 说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调返回一个新的promise对象2-3.Promise.prototype.catch 方式:(onRejected) => {}
 1. onRejected函数:失败的回调函数 (reason) =>{}2-4.Promise.resolve(参数) => {}
1.传入非primise对象,例如:字符串,num ,布尔等,返回都是成功的回调
 2.传入一个promise对象,返回的结果根据promise的结果而决定
// 传入非primise对象,例如:字符串,num ,布尔等,返回都是成功的回调        let p = Promise.resolve(520)                // 传入一个promise对象,返回的结果根据promise的结果而决定        let p1 = Promise.resolve(new Promise((resolve,reject)=>{            // resolve('ok')            reject('error')        }))         console.log('p',p);        console.log('p1',p1);
2-5.Promise.reject(参数) => {}
1.不管传入什么返回的都是错误的回调
 2.传入string , number , 布尔 , undefine,或者promise对象返回的都是错误的回调
let p = Promise.reject('123')        let p1 = Promise.reject((resolve,reject)=>{            resolve('ok')        })        console.log(p);        console.log(p1);
2-6.Promise.all(数组) => {}
包含n个数组
 说明:返回一个新的promise,只有所有的promise都成功才成功,有一个失败就都失败
let p1 = new Promise((resolve,reject)=>{                resolve('ok1')        })        let p2 = new Promise((resolve,reject)=>{                resolve('ok2')        })        let p3 = new Promise((resolve,reject)=>{                resolve('ok3')        })        const res =  Promise.all([p1,p2,p3])        console.log(res);

2-7.Promise.race(数组) => {}
包含n个数组
 说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
let p1 = new Promise((resolve,reject)=>{                resolve('ok1')        })        let p2 = new Promise((resolve,reject)=>{                resolve('ok2')        })        let p3 = new Promise((resolve,reject)=>{                reject('ok3')        })        const res =  Promise.race([p1,p2,p3])        console.log(res);
三、Promise关键问题
3-1.如何修改对象的状态
三个方法:
 1.resolve ==> pending ==> 转换为 resolve
 2.reject ==> pending ==> 转换为 reject
 3.throw ==> pending ==> 转换为 throw抛出一个错误
let p = new Promise((resolve,reject)=>{            // resolve('success') pending ==> 转换为 resolve            // reject('error')    pending ==> 转换为 reject            throw('我出错了')    //pending ==> 转换为 throw        })        console.log(p);3-2.能否执行多个回调
可以:只要promise的状态确定了
let p = new Promise((resolve,reject)=>{            resolve('ok')        })        p.then(res=>{            console.log(res);        })        p.then(res=>{            console.log(res);        })
3-3.改变promise状态和指定回调函数谁先谁后
 1. 都有可能,正常情况下时先指定回调函数再改变状态,但是也可以先改变状态再指定回调 2. 如何先该状态再指定回调(1)在执行器中直接调用resolve()/reject()(2)延长更长的时间才调用then()  3. 什么时候才可以得到数据(1)如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据(2)如果先改变状态,那当指定回调时,回调函数就会调用,得到数据执行器中如果是同步任务,就会先改变状态再执行回调
let p = new Promise((resolve,reject)=>{            resolve('ok')        })        p.then(res=>{            console.log(res);        })执行其中如果是异步任务,就会先执行回调再改变状态
let p = new Promise((resolve,reject)=>{            setTimeout(()=>{                resolve('ok')            },1000)        })        p.then(res=>{            console.log(res);        })3-4.promise.then方法返回结果由什么决定
1.抛出问题 ==> PromiseState:"reject"throw '出错了'2.返回结果是非Promise类型的对象 ==> PromiseState:"fulfilled"return 1233.返回结果是一个Promise对象 ==> PromiseState:"resolve/reject"let p = new Promise((resolve, reject) => {            resolve('ok')        })        let results = p.then((value) => {            // console.log(value);            // 1.抛出问题 ==> PromiseState:"reject"            // throw '出错了'            // 2.返回结果是非Promise类型的对象 ==> PromiseState:"fulfilled"            // return 123            // 3.返回结果是一个Promise对象 ==> PromiseState:"resolve/reject"            return new Promise((resolve,reject)=>{                  // resolve('success')                reject('error')            })        }, reason => {            console.log(reason);        })        console.log(results);
3-5.Promise如何让串联多个操作任务
 1. promise的then()返回一个新的promise,可以开成then()的链式调用 2. 通过then的链式调用串联多个同步/异步任务let p = new Promise((resolve,reject) => {            setTimeout(()=>{                resolve('ok')            },1000)        })        p.then(value => {            console.log(value); // ==> ok            return new Promise((resolve,reject) => {                resolve('success')            })        }).then(value=>{            console.log(value); // ==> success        }).then(value=>{            console.log(value); // ==> undefine        })        
3-6.异常穿透
 1. 串联多个任务后,直接再最后面添加一个catch就可以捕获之前的错误let p = new Promise((resolve,reject)=>{            setTimeout(()=>{                resolve('ok')                // reject('error')            },1000)        })        p.then(value => {            console.log(111);             throw('出错了')        }).then(value=>{            console.log(222);        }).then(value=>{            console.log(333);        }).catch(reason=>{            console.warn(reason);        })
3-7.中断promise链
 1. 一直.then就会形成promise链 2. 中断promise链只有一个方式就是return一个pending的promise对象 3. 如果返回的是其他的值都是一个成功的对象,都会往下执行 let p = new Promise((resolve,reject)=>{                resolve('ok')        })        p.then(value => {            console.log(111);             return new Promise(()=>{                            })        }).then(value=>{            console.log(222);        }).then(value=>{            console.log(333);        }).catch(reason=>{            console.warn(reason);        })
四、Promise自定义封装
在本博客的资源里面有手写好的Promise五、async与await
5-1.async表达式
 1. 函数的返回值为promise对象 2. promise对象的结果由async函数的返回值决定的         async function main(){            // 1.如果返回值是以恶搞非promise类型的数据            // return '123'            // 2.如果返回的是一个promise象            // return new Promise((resolve,reject)=>{            //     // resolve('ok')            //     reject('error')            // })            // 3.抛出异常            throw '出错了'        }        //返回的是一个promise对象        let res = main()        console.log(res);

5-2.await表达式
 1. await右侧的表达式一般为promise对象,但是也可以是其他的值 2. 如果表达式时peomise对象,await返回的是promise成功的值 3. 如果表达式是其他值,直接将此值作为await的返回值 4. await必须写在async函数中,但是async函数中可以没有await 5. 如果await的peomise失败了,就会抛出异常,需要通过try,catch捕获处理async function main(){            let p = new Promise((resolve,reject)=>{                // resolve('ok')                reject('error')            })            // 1.右侧为promise的情况            // let res = await p            // 2.右侧为其他数据类型            // let res1 = await 66            // 3.如果promise是失败的状态            try {                let res3 = await p            } catch (error) {                console.log(error);            }        }        main()5-3.async和await实战结合
访问文件并且拼接
const fs = require('fs')const util = require('util')const myReadFile = util.promisify(fs.readFile)async function main(){    let data1 = await myReadFile('./实战/resource/1.html')    let data2 = await myReadFile('./实战/resource/2.html')    console.log(data1+data2);}main()