为了账号安全,请及时绑定邮箱和手机立即绑定

你是否真正自己手写过一个promise?

标签:
Vue.js

writing-promise

你是否真正自己手写过一个promise?

想过这些问题没有?

  • 什么是promise?
  • promise诞生的意义是什么,为什么会有promise?
  • promise的Api有哪些?
  • 如何使用这些Api呢?(mdn有详细的用法,详细的不能太详细)
  • 终极解决方案async/await的使用!
  • 手写一个promise吧!

什么是promise?

抽象表达:Promise 是JS 中进行异步编程的新的解决方案
具体表达:Promise 是一个构造函数,promise对象用来封装一个异步操作并可以获取其结果

promise诞生的意义是什么,为什么会有promise?

1.指定回调函数的方式更加灵活
promise之前:必须在启动异步任务前指定
promise:启动异步任务=> 返回promie 对象=> 给promise 对象绑定回调函
数(甚至可以在异步任务结束后指定/多个)
2.支持链式调用, 可以解决回调地狱问题
什么是回调地狱? 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调函数执行的条件
回调地狱的缺点? 不便于阅读/ 不便于异常处理
解决方案? promise 链式调用
终极解决方案? async/await

promise的Api有哪些?

1.Promise 构造函数: Promise (excutor) {}
2.Promise.prototype.then 方法: (onResolved, onRejected) => {}
3.Promise.prototype.catch 方法: (onRejected) => {}
4.Promise.resolve 方法: (value) => {}
5.Promise.reject 方法: (reason) => {}
6.Promise.all 方法: (promises) => {}
7.Promise.race 方法: (promises) => {}

手写一个promise吧!

/**
 * 自定义Promsie函数
 */

(function(window) {

    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';
    
    class Promise {
        constructor(excutor) {
            const self = this;

            self.status = PENDING; // promise对象状态
            self.data = undefined; // promise对象指定一个用于存储结果数据的属性
            self.callbacks = []; // 待执行的回调函数

            function resolve(value) {
                if (self.status === PENDING) {
                    self.status = RESOLVED;
                    self.data = value;
                    if(self.callbacks.length > 0) {
                        setTimeout(() => { // 模拟宏队列任务
                            self.callbacks.forEach((callbanckObj) => {
                                callbanckObj.onResolved(value);
                            });
                        });
                    }
                }
            }

            function reject(reason) {
                if (self.status === PENDING) {
                    self.status = REJECTED;
                    self.data = reason;
                    if(self.callbacks.length > 0) {
                        setTimeout(() => {// 模拟宏队列任务
                            self.callbacks.forEach((callbanckObj) => {
                                callbanckObj.onRejected(reason);
                            });
                        });
                    }
                }
            }

            try {
                excutor(resolve, reject);
            } catch (error) {
                reject(error);
            }
        }

        /**
         * Promise原型对象的then()
         * 指定成功和失败的回调函数
         * 返回一个新的Promise
         */
        then(onResolved, onRejected) {

            const self = this;

            onResolved = typeof onResolved === 'function' ? onResolved : value => value;

            onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

            return new Promise((resolve, reject) => {

                function handle(callback) {
                    try {
                        const result = callback(self.data);
                        if (result instanceof Promise) {
                            result.then(resolve, reject);
                        } else {
                            resolve(result);
                        }
                    } catch (error) {
                        reject(error);
                    }
                }

                if (self.status === PENDING) {
                    self.callbacks.push({
                        onResolved() {
                            handle(onResolved);
                        },
                        onRejected() {
                            handle(onRejected);
                        }
                    });
                } else if (self.status === RESOLVED) {
                    setTimeout(() => {
                        handle(onResolved);
                    });
                } else if (self.status === REJECTED) {
                    setTimeout(() => {
                        handle(onRejected);
                    });
                }
            });
        }

        /**
         * Promise原型对象的catche()
         * 失败的回调函数
         * 返回一个新的Promise
         */
        catch(onRejected) {
            return this.then(undefined, onRejected);
        }
        
        /**
         * Promise函数对象resolve()
         * 返回一个指定结果成功的Promise
         */
        static resolve = function (value) {
        return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(resolve, reject);
                } else {
                    resolve(value);
                }
        });
        }

        /**
         * Promise函数对象reject()
         * 返回一个指定rason的失败的Promise
         */
        static reject = function (reason) {
            return new Promise((resolve, reject) => {
                reject(reason);
            });
        }

        /**
         * Promise函数对象all()
         * 返回一个Promsise,只有当所有promise都成功时才成功,否则失败
         */
        static all = function (promises) {

            const values = new Array(promises.length);
            let count = 0;

            return new Promise((resolve, reject) => {
                promises.forEach((promise, index) => {
                    Promise.resolve(promise).then(
                        value => {
                            count++;
                            values[index] = value;
                            if (count === promises.length) {
                                resolve(values);
                            }
                        },
                        reason => {
                            reject(reason);
                        }
                    )
                })
            });
        }

        /**
         * Promise函数对象race()
         * 返回一个Promsise,其结果由第一个完成的promise决定
         */
        static race = function (promises) {
            return new Promise((resolve, reject) => {
                promises.forEach(promise => {
                    Promise.resolve(promise).then(resolve, reject);
                });
            });
        }
    }
    
    // 向外暴露Promise函数
    window.Promise = Promise;
})(window);
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
15
获赞与收藏
30

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消