尚硅谷Promise笔记

一、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的值有三个

  1. pending 待定的状态
  2. resolve 成功的状态
  3. 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 123
3.返回结果是一个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()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忧郁火龙果

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值