Promise学习笔记

目录大纲

  • 初识Promise
    • 1)Promise是什么 2)Promise基本用法
  • Promise的实例方法
    • 1)then() 2)cach 3)finally()
  • Promise 的构造函数方法
    • 1)Promise.resolve() 2)Peomise.reject() 3)Peomise.all() 4)Promise.race() 5)Promise.allSettled()
  • Promise的注意事项以及应用
    • 1)Promise注意事项 2)Promise 的应用

一、初识Promise

1、Promise是什么

Promises是异步操作的一种解决方案
认识回调函数:

        document.addEventListener('click', () => {
            console.log('这是异步函数')
        })
        console.log('这是同步函数')

2、什么时候使用Promise

Promise 一般用来解决层层嵌套的回调函数(回调地狱 callback hell)的问题
回调地狱问题案例:

        const move = (el, { x = 0, y = 0 } = {}, end = () => { }) => {
            el.style.transform = `translate3d(${x}px,${y}px,0)`
            el.addEventListener('transitionend', () => {
                end()
            })
        }
        let BOX = document.getElementById('box')
        document.addEventListener('click', () => {
            move(BOX, { x: 10 }, () => {
                move(BOX, { x: 10, y: 50 }, () => {
                    move(BOX, { x: 40, y: 50 }, () => {
                        move(BOX)
                    })
                })
            })
        })

3、Promise的基本用法

1)、实例化构造函数的生成的实例对象

基本语法
 const p = new Promise(() => { })

2)、Promise的状态

Promise的状态一旦变化,就不会变

Promise有3种状态,一开始是pending(未完成),执行resolve,变成fulfilled(resolved),已成功;
执行 reject ,变成rejected ,已失败

      const p1 = new Promise((resolve, reject) => {
            // Promise有3种状态,一开始是pending(未完成),执行resolve,变成fulfilled(resolved),已成功
            // 执行  reject ,变成rejected ,已失败
            resolve()
            reject()

            // Promise的状态一旦变化,就不会变

        })
        console.log(p1) //Promise {<pending>}=>等待状态
        //Promise {<fulfilled>: undefined} =>成功
        //Promise {<rejected>: undefined} =>失败
        // 3、then方法

3)、resolve() reject() 参数

        const p2 = new Promise((resolve, resject) => {
            // resolve({name:"HI"})
            resject(new Error('失败元婴'))
        })
        p2.then((res) => {
            console.log(res)
        }, (res) => {
            console.log(res)
        })

二、Promise的实例方法

1、then方法

        p1.then(() => {
            console.log('成功') //成功
        }, () => {
            console.log('失败')
        })

1)、什么时候执行?

pending->fulfilled 时,执行 then的第一个回调函数
pending->rejected 时,执行 then的第二个回调函数

2)、执行后的返回值
then方法执行后返回一个新的Promise对象

       const p3 = new Promise((resolve, reject) => {
            resolve()
        })
        p3.then(() => {
        }, () => {
        }).then(() => {
        }, () => { })

3)、then方法返回的Promise对象的状态改变

        const p4 = new Promise((resolve, reject) => {
            resject(new Error('你失败'))
        })
        p4.then((res) => { }, () => {
            // 在then的回调函数中,return 后面的东西,底层会用Promise包装下,
            return { text: '给下一个then使用' }
            //  以上写法等同于
            return new Promise((resovle, reject) => {
                // 默认返回都是成功状态下的Promise对象
                resovle({ text: '给下一个then使用' })
            })


            // 注意如果你需要下一个then走失败:
            return new Promise((resolve, reject) => {
                reject('需要手动写失败')
            })

            console.log(res)
        }).then((res) => {
            console.log('第二个then:', res) //第二个then: {text: "给下一个then使用"}
        }, (res) => {
            console.log(res) //需要手动写失败
        })

个人总结:第一个then,根据Promise决定成功与失败,后续的then方法根据上一个then,决定
后面的then,默认执行的都是成功状态下Promise,需要手动写执行reject

2、使用Promise解决回调地狱问题

        const moveTwo = (el, { x = 0, y = 0 } = {}, end = () => { }) => {
            el.style.transform = `translate3d(${x}px,${y}px,0)`
            el.addEventListener('transitionend', () => {
                end()
            })
        }
        let BOX2 = document.getElementById('box2')
        const movePromise = ((el, point) => {
            return new Promise((resolve, reject) => {
                moveTwo(el, point, () => {
                    resolve();
                })
            })
        })
        document.addEventListener('click', () => {
            movePromise(BOX2, { x: 150 }).then(() => {
                return movePromise(BOX2, { y: 150 })
            }).then(_ => {
                return movePromise(BOX2, { x: 150 })
            })
        })

3、catch()

then可以处理成功失败状态,一般then习惯处理成功状态
catch专门用来处理rejected状态
基本用法:

        new Promise((resovle, reject) => {
            resovle(123)
        }).then(_ => {
            //throw 简写失败结果
            throw new Error('9999')
        })
            .then((null,err=>{})) // 同下
            .catch(err => {
                console.log(err)
            })
  catch()可以捕获它前面的错误,
  一般总是建议, Promise对象后面要眼catch方法,这样可以处理Promise内部发生的错误

4、了解finally()

什么时候执行?:当Promise状态发生变化时,不论如何变化都会执行,不变化不执行
本质: finally()本质上是then的特例

        new Promise((resovle, reject) => {
            reject(11)
        }).catch(_ => {
            console.log(_)
        }).finally(_ => {
            // 每次都执行
        })

三、 Promise 的构造函数方法

1、Promise.resolve()和Promise.reject()

1)Promise.resolve()是成功状态的一种简写是形式

        new Promise(resolve => { })
        // 简写:
        Promise.resolve('f

2)Promise.resolve参数
一般参数

   Promise.resolve('我是成功状态,哈哈哈哈哈哈哈').then(res => { console.log(res) })在这里插入代码片

Promise参数

        const pN = new Promise((resolve, reject) => {
            // setTimeout(() => {
            //     resolve('我在1000秒后执行')
            // }, 1000);
            setTimeout(resolve, 1000, '我在1000秒后执行');
        })

        Promise.resolve(pN).then(data => {
            console.log(data) //我在1000秒后执行
        })
        // 等同于
        pN.then(data => {
            console.log(data) //我在1000秒后执行
        })

当resolve’函数接收的是Promise对象时,后面的then会根据传递的Promise对象的状态变化决定执行哪一个回调

        new Promise(resovle => resovle(pN)).then(data => {
            console.log(data) //我在1000秒后执行
        })

具有then方法的对象

        const thenable = {
            then() {
                console.log('我是then,在对对象中')
            }
        }
        Promise.resolve(thenable).then(sus => console.log(sus), err => console.log(err))
        console.warn(Promise.resolve(thenable), '标记') //Promise {<pending>}[[Prototype]]: Promisecatch: ƒ catch()constructor: ƒ Promise()finally: ƒ finally()then: ƒ then()Symbol(Symbol.toStringTag): "Promise"[[Prototype]]: Object[[PromiseState]]: "pending"[[PromiseResult]]: undefined "标记"

2)Promise.reject()
失败状态Promise的一种简写形式
基本语法:

        new Promise((resolve, reject) => {
            reject('失败')
        })
        //  等同于
        Promise.reject('失败')

参数:不管什么参数,都会原封不动地向后传递,作为后续方法的参数

        const ps = new Promise(resolve => {
            setTimeout(resolve, 1000, '我执行l');
        })
        Promise.reject(ps).catch(err => console.log(ps)) //Promise实例

2、执行流程方法

        new Promise((resolve, reject) => {
            resolve('哈哈')
        }).then(res => {
            //   执行成功的三种写法
            return '成功'
            return new Promise(resolve => resolve('成功'))
            return Promise.resovle('成功')
            //   执行失败的三种写法
            throw '失败'
            return new Promise((resolve, reject) => reject('失败'))
            return Promise.reject('失败')
        })

3、Promise.all()

Promise.all()关注多个Promise对象的的状态变化
传入多个Promise实例,包装成一个新的Promise 实例返回
基本用法

        const delay = ms => {
            return new Promise(resovle => { setTimeout(resovle, ms); })
        }
        const all1 = delay(1000).then(() => {
            console.log('all1我执行完成:')
            return 'all1在all方法中'
        })
        const all2 = delay(2000).then(() => {
            console.log('all2我执行完成:')
            throw 'all2在all方法中'
        })

        Promise.all([all1, all2]).then(res => {
            console.log(res) //[ "all1在all方法中","all2在all方法中"]
        }).catch(res => console.log('标记', res))

4、Promise.race()

Promise.race() 的状态取决于第一个完成的Promise实例对象如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败(赛跑,谁先执行返回谁)

        const delaytwo = ms => {
            return new Promise(resovle => { setTimeout(resovle, ms); })
        }
        const race1 = delaytwo(1000).then(() => {
            console.log('race1:')
            return 'race1在race方法中'
        })
        const race2 = delaytwo(2000).then(() => {
            console.log('race1')
            throw 'race2在race方法中'
        })
        Promise.race([all1, all2]).then(res => {
            console.log(res)
        }).catch(res => console.log(res))

5、Promise.allSettled()

  1. Promise.allSettled()的状态与传入的Promise 状态无关
  2. 永远都是成功的
  3. 它只会忠实的记录下各个Promise的表现(结果)
       const delaythree = ms => {
            return new Promise(resovle => { setTimeout(resovle, ms); })
        }
        const allSettled1 = delaythree(1000).then(() => {
            return 'allSettled1方法成功状态'
        })
        const allSettle2 = delaythree(2000).then(() => {
            throw 'allSettle2方法成功状态'
        })
        Promise.allSettled([allSettled1, allSettle2]).then(res => {
            console.log(res)  //(2) [{…}, {…}]
        })

四、Promise注意事项以及应用

1、Promise注意事项

     * resolve或reject执行后的代码
     * Promise.all/race/allSettled的参数问题
     * Promise.all/race/allSettled的错误处理

1.resolve或reject函数执行后的代码:推荐在调用resolve或reject函数的时候加上return,不再执行它们后面的代码

        new Promise((resolve, reject) => {
            return resolve('HHHHH')
        })

2.Promise.all/race/allSettled的参数问题//参数如果不是Promise数组, 会将不是Promise的数组元素转变成Promise对象

        Promise.all([1, 2, 3]).then(res => console.log(res)) //(3) [1, 2, 3]
        //等同于
        Promise.all([
            Promise.resolve(1),
            Promise.resolve(2),
            Promise.resolve(3)
        ]).then(res => console.log(res)) //[1, 2, 3]

3、任何可遍历的都可以作为参数

数组、字符串、Set.Map.NodeList.arguments
Promise.all(new Set([1, 2, 3])).then(res => console.log(res)) // [1, 2, 3]

2、Promise应用

图片异步加载

        const loadImgAsync = url => {
            return new Promise((resolve, reject) => {
                const img = new Image()
                img.onload = () => { resolve(img) }
                img.onerror = () => { reject('图片加载失败') }
                img.src = url
            })
        }
        const DOMimg = document.getElementById('img')
        loadImgAsync('https://finance-glb-mx.s3.us-west-2.amazonaws.com/upload/pro/i/202108/16301107832998634.jpg  ')
            .then(res => {
                console.log(res,7888888888888888888)
                DOMimg.src = res.src

            })
            .catch(res => console.log(res))


上一篇:如何编写一个简单的依赖注入容器


下一篇:Vue.js CLI4 Vue.config.js标准配置 (最全注释)