美文网首页
手写 Promise 简单梳理

手写 Promise 简单梳理

作者: 弱冠而不立 | 来源:发表于2020-11-15 13:14 被阅读0次

推荐文章

Promise 基本特征

  1. promise 有三个状态:pending、fulfilled、rejected(未决定,履行,拒绝)。初始化,状态:pending;
  2. executor接受两个参数,分别是resolve和reject;
    executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回所建promise实例对象前被调用)。当调用resolve(成功),状态:pengding=>fulfilled。当调用reject(失败),状态:pending=>rejected;
  3. promise 有一个value保存成功状态的值,可以是undefined/thenable/promise;
  4. promise 有一个reason保存失败状态的值;
  5. promise 只能从pending到rejected, 或者从pending到fulfilled,状态一旦确认,就不会再改变;
  6. promise 必须有一个then方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled, 和 promise 失败的回调 onRejected;
  7. 如果调用 then 时,promise 已经成功,则执行onFulfilled,参数是promise的value;
  8. 如果调用 then 时,promise 已经失败,那么执行onRejected, 参数是promise的reason;
  9. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个 then 的失败的回调onRejected;

初级版本,能解决成功运行同步,但是异步就没有输出

    // 定义三个状态
    const PENDING = 'PENDING';
    const FULFILLED = 'FULFILLED';
    const REJECTED = 'REJECTED';

    class MyPromise {
        constructor(executor) {
            // 默认状态为PENDING
            this.status = PENDING;
            // 存放成功状态的值,默认为 undefined
            this.successValue = undefined;
            // 存放失败状态的值,默认为 undefined
            this.failValue = undefined;

            // 执行成功时的回调
            const resolve = (successValue) => {
                // 状态为 PENDING 时才可以更新状态,防止 executor 中调用了两次 resovle/reject 方法
                if (this.status === PENDING) {
                    this.status = FULFILLED
                    this.successValue = successValue
                }
            }

            // 执行失败的回调
            const reject = (failValue) => {
                if (this.status === PENDING) {
                    this.status = REJECTED
                    this.failValue = failValue
                }
            }

            // 执行时判断报不报错,报错就抛出异常执行失败的回调
            try {
                executor(resolve, reject)
            } catch (error) {
                // 发生异常时执行失败
                reject(error)
            }
        }

        /**
        * 包含一个 then 方法,并接收两个参数
        * 一个是成功时的回调
        * 一个是失败时的回调
        **/
        then(onFulfilled, onRejected) {
            if (this.status === FULFILLED) {
                onFulfilled(this.successValue)
            }
            if (this.status === REJECTED) {
                onRejected(this.failValue)
            }
        }
    }

来试用一下:

    const test_sync = new MyPromise((resolve, reject)=>{
        resolve("同步成功")
    })
    console.log(test_sync);
    test_sync.then(res=>{
        console.log(res);
    })

    const test_async = new MyPromise((resolve, reject) => {
        setTimeout(()=>{
            resolve("异步成功")
        }, 100)
    })
    console.log(test_async);
    test_async.then(res=>{
        console.log(res);
    })
因为 promise 调用 then 方法时,当前的 promise 并没有成功,一直处于 pending 状态。所以如果当调用 then 方法时,当前状态是 pending,我们需要先将成功和失败的回调分别存放起来,在executor()的异步任务被执行时,触发 resolve 或 reject,依次调用成功或失败的回调

基础版本解决异步输出

    // 定义三个状态
    const PENDING = 'PENDING';
    const FULFILLED = 'FULFILLED';
    const REJECTED = 'REJECTED';

    class MyPromise {
        constructor(executor) {
            // 默认状态为PENDING
            this.status = PENDING;
            // 存放成功状态的值,默认为 undefined
            this.successValue = undefined;
            // 存放失败状态的值,默认为 undefined
            this.failValue = undefined;
            // 存放成功的回调
            this.onResolvedCallbacks = [];
            // 存放失败的回调
            this.onRejectedCallbacks = [];

            // 执行成功时的回调
            const resolve = (successValue) => {
                // 状态为 PENDING 时才可以更新状态,防止 executor 中调用了两次 resovle/reject 方法
                if (this.status === PENDING) {
                    this.status = FULFILLED
                    this.successValue = successValue
                    // 依次将对应的函数执行
                    this.onResolvedCallbacks.forEach(fn => fn())
                }
            }

            // 执行失败的回调
            const reject = (failValue) => {
                if (this.status === PENDING) {
                    this.status = REJECTED
                    this.failValue = failValue
                    // 依次将对应的函数执行
                    this.onRejectedCallbacks.forEach(fn => fn())
                }
            }

            // 执行时判断报不报错,报错就抛出异常执行失败的回调
            try {
                executor(resolve, reject)
            } catch (error) {
                // 发生异常时执行失败
                reject(error)
            }
        }

        /**
        * 包含一个 then 方法,并接收两个参数
        * 一个是成功时的回调
        * 一个是失败时的回调
        **/
        then(onFulfilled, onRejected) {
            // 如果promise的状态是 pending,需要将 onFulfilled 和 onRejected 函数存放起来,等待状态确定后,再依次将对应的函数执行
            if (this.status === PENDING) {
                this.onResolvedCallbacks.push(() => {
                    onFulfilled(this.successValue)
                })
                this.onRejectedCallbacks.push(() => {
                    onRejected(this.failValue)
                })
            }
            if (this.status === FULFILLED) {
                onFulfilled(this.successValue)
            }
            if (this.status === REJECTED) {
                onRejected(this.failValue)
            }
        }
    }

试用一下异步:

    const test_sync = new MyPromise((resolve, reject) => {
        resolve("同步成功")
    })
    console.log(test_sync);
    test_sync.then(res => {
        console.log(res);
    })

    const test_async = new MyPromise((resolve, reject) => {
        setTimeout(() => {
            resolve("异步成功")
        }, 100)
    })
    console.log(test_async);
    test_async.then(res => {
        console.log(res);
    })

相关文章

  • 手写 Promise 简单梳理

    推荐文章[https://juejin.im/post/6850037281206566919#heading-3...

  • 手写promise

    手写promise 带大家手写一个 promis。在手写之前我会先简单介绍一下为什么要使用promise、prom...

  • 手写Promise(简单)

    Promise Promise.all Promise.race

  • 手写Promise

    手写 Promise 我们会通过手写一个符合 Promise/A+ 规范的 Promise 来深入理解它,并且手写...

  • 手写极简版promise

    为了更更加好的理解promise ,简单的学习了一下手写promise。于是我就简单的学了一下 ,首先分步操作,先...

  • 手写 Promise 系列 --- 3

    在前两篇(手写 Promise 系列 --- 1)和(手写 Promise 系列 ---2) 中,达成了3个目标 ...

  • 手写Promise

    $ 正常的promise用法   $ 手写的Promise   # 测试可行性

  • 纯手写实现自己的nodejs promise 库

    纯手写实现自己的nodejs promise 库什么是Promise?promise 链Async/Await后续...

  • 手写promise

    面试的笔试题中遇到过手写promise的题目,以下是参考了网上的文章,自己整理的一个简单的promise函数:

  • 手写基础 promise

    1. 前言 玩下吧 手写 promise,看看能写成啥样 2. promise 基础结构 3. 手写`promi...

网友评论

      本文标题:手写 Promise 简单梳理

      本文链接:https://www.haomeiwen.com/subject/yzbhektx.html