Promise的学习笔记1

(What)什么是Promise?
  • Promise是异步编程的新的解决方案,比起旧的解决方案(回调)更合理更强大。

    • 从语法上来说:Promise是一个构造函数
    • 从功能上来说:Promise对象用来封装一个异步操作并可以获取其结果
  • Promise的状态改变

  1. 调用resolve函数来将promise当前状态pending(进行中)改成fulfilled(已成功)
  2. 调用reject函数来将promise当前状态pending(进行中)改成rejected(已失败)

说明:只有这2种状态的改变,且promise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason。

  • Promise的基本流程
执行
执行resolve
执行reject
.then
.then/catch
return
return
Promise
异步操作
fulfilled状态
rejected状态
onFulfillment
onRejection
新的Promise
  • Promise的基本使用

根据上述Promise的基本流程实现一个Promise的基本使用。
定义一个全局的常量,该常量为[1,10]之间的随机整数。若该常量为偶数,Promise状态为fulfilled,调用 resolve(value);若该常量为奇数,Promise状态为rejected调用reject(reason)

        const num = Math.floor(Math.random() * 10 + 1)
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                if (num % 2 == 0) {
                    resolve('fulfilled状态')
                } else {
                    reject('rejected状态')
                }
            }, 1000);
        })
        p.then(
            value => {
                console.log('onFulfillment,num is ' + num)
            },
            reason => {
                console.log('onRejection,num is ' + num)
            }
        )
(Why)为什么要用Promise?
  • 指定回调函数的方式更加灵活(旧的解决方案必须在启动异步任务前指定回调函数)
  • 支持链式调用,可以解决回调地狱问题
    • 回调地狱
      • 什么是回调地狱?什么时候会使用回调地狱?回调地狱的缺点?
        //回调地狱
        doSomenthing(function (result) {
            doSecondThing(result, function (secondResult) {
                doThirdThing(newResult, function (thirdResult) {
                    console.log(thirdResult);
                }, failureCallback)
            }, failureCallback)
        }, failureCallback)

以上代码简单的描述了回调地狱。在多个串联的异步操作会出现回调地狱。回调地狱的缺点:以前一个异步任务的结果为条件;回调函数嵌套使得代码难以阅读;异常处理分别输出。

  • 使用Promise解决回调地狱
        doSomenthing()
            .then(function (result) {
                return doSecondthing(result)
            })
            .then(function (secondResult) {
                return doThirdthing(secondResult)
            })
            .then(function (thirdResult) {
                console.log(thirdResult);
            })
            .catch(failureCallback)
  • 使用async/await解决回调地狱
        async function request() {
            try {
                const result = await doSomething()
                const secondResult = await doSecondthing()
                const thirdResult = await doThirdthing()
                console.log(thirdResult);
            } catch (error) {
                failureCallback
            }
        }
(How)如何使用Promise?
  • Promise构造函数:executor
     new Promise((resolve, reject) => {...} /* executor */ );

Promise构造函数执行时立即调用executor 函数,分别将promise的状态改为fulfilled(完成)或rejected(失败)。

  • Promise.prototype.then()
        p.then(onFulfilled[, onRejected]);
        p.then(value => {
            // fulfillment
        }, reason => {
            // rejection
        });

内部定义成功时的回调函数(value)=>{},内部定义失败时的回调函数(reason)=>{}。

  • Promise.prototype.catch()
        p.catch(onRejected);

        p.catch(function (reason) {
            // 拒绝
        });

失败时的回调函数(reason)=>{},then()的语法糖,相当于then(undefined, onRejected)

  • Promise.resolve()
        const testResolve = Promise.resolve('返回一个以给定值解析后的Promise 对象');
        testResolve.then((value) => {
            console.log(value);
            // expected output: 返回一个以给定值解析后的Promise 对象
        });
  • Promise.reject()
        const testReject = Promise.reject('返回一个失败的对象');
        //reason:失败原因
        testReject.then((reason) => {
            console.log(reason);
            // expected output: 返回一个失败的对象
        });

结合上述五个写一个简单的例子

        const testPromise = new Promise((resolve, reject) => {
            //executor函数
            setTimeout(() => {
                // resolve('我是成功数据')
                reject('我是失败数据')
            }, 1000);
        }).then(
            value => {
                console.log(value)
            }
        ).catch(
            reason => {
                console.log(reason)
            }
        )
  • Promise.all()
        const p1 = Promise.resolve(1)
        const p2 = Promise.resolve(2)
        const p3 = Promise.reject(3)
        const p4 = Promise.reject(4)
        const pAll = Promise.all([p2, p1]) //[p1,p2,p4,p3]
        pAll.then(
            values => {
                console.log('我们是成功数据' + values);
            }
        ).catch(
            reason => {
                console.log('我是失败数据' + reason);
            }
        )

如果所有参数都成功(resolved),此实例回调成功(resolve),按调用all的参数顺序输出
此时输出的结果为:我们是成功数据2,1。

如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。若将参数[p2, p1]换成[p1,p2,p4,p3]。
此时输出的结果为:我是失败数据4。

  • Promise.race()
        const p1 = Promise.resolve(1)
        const p2 = Promise.resolve(2)
        const p3 = Promise.reject(3)
        const p4 = Promise.reject(4)
        const pRace = Promise.race([p2, p1])
        pRace.then(
            values => {
                console.log('我们是成功数据' + values);
            }
        ).catch(
            reason => {
                console.log('我是失败数据' + reason);
            }
        )

第一个完成的promise的结果状态就是最终的结果状态

猜你喜欢

转载自blog.csdn.net/xicc1112/article/details/104576244