2019-08-30 小谈promise(附源码)

一直想发表自己得第一篇文章,无奈自己是一个中度懒癌患者。就自己认为在前端开发中遇到的一些小问题和自己旁听到得一些知识与大家分享。 如有不对,欢迎大家指正!


今天首先想说的是关于promise得源码解析,关于原型上then,catch和all方法源码的分享。

众所周知,js中所有代码是单线程执行的。这就导致,js中所有的网络操作,请求数据都必须是异步执行。当然异步执行可以用回调函数实现:

functioncallback(){console.log('Done');}

console.log('before setTimeout()');

setTimeout(callback,1000);// 1秒钟后调用callback函数

console.log('after setTimeout()');

输出后:

before setTimeout()

after setTimeout()

(等待1秒后)

Done;


这是简单的异步运行的例子。但是我们设想如果一个回调里嵌入另一个回调,第二个回调有用到第三个回调。。。就会形成可怕的“回调地狱”。不仅代码维护成本高,并且可读性很差。Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

下面就是promise源码:


class Promise {

    constructor(excutor) {

        this.status = 'pending';

        this.value = undefined;

        this.fulfilledAry = [];

        this.rejectedAry = [];

        //=>成功和失败执行的方法

        let resolve = result => {

            let timer = setTimeout(() => {

                clearTimeout(timer);

                if (this.status !== 'pending') return;

                this.status = 'fulfilled';

                this.value = result;

                this.fulfilledAry.forEach(item => item(result));

            }, 0);

        };

        let reject = reason => {

            let timer = setTimeout(() => {

                clearTimeout(timer);

                if (this.status !== 'pending') return;

                this.status = 'rejected';

                this.value = reason;

                this.rejectedAry.forEach(item => item(reason));

            }, 0);

        };

        //=>捕获异常信息

        try {

            excutor(resolve, reject);

        } catch (e) {

            reject(e);

        }

    }

    //=>THEN(then方法看完 相信大家也都明白为什么可以实现链式调用)

    then(fulfilledCallBack, rejectedCallBack) {

        typeof fulfilledCallBack !== 'function' ? fulfilledCallBack = () => {

            return this.value;

        } : null;

        typeof rejectedCallBack !== 'function' ? rejectedCallBack = () => {

            throw new Error(this.value);

        } : null;

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

                    this.fulfilledAry.push(() => {

                        try {

                    let x = fulfilledCallBack(this.value);

                    x instanceof Promise ? x.then(resolve, reject) : resolve(x);

                } catch (e) {

                    reject(e);

                }

            });

            this.rejectedAry.push(() => {

                try {

                    let x = rejectedCallBack(this.value);

                    x instanceof Promise ? x.then(resolve, reject) : resolve(x);

                } catch (e) {

                    reject(e);

                }

            });

        });

    }

    //=>CATCH

    catch(rejectedCallBack) {

        return this.then(null, rejectedCallBack);

    }

    //=>STATIC ALL

    static all(promiseAry) {

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

            let resultAry = [],

                index = 0;

            for (let i = 0; i < promiseAry.length; i++) {

                promiseAry[i].then(result => {

                    index++;

                    resultAry[i] = result;

                    if (index === promiseAry.length) {

                        resolve(resultAry);

                    }

                }).catch(reason => {

                    reject(reason);

                });

            }

        });

    }

}

module.exports = Promise;

如果有不明白的地方,可以看看https://blog.csdn.net/qq_34645412/article/details/81170576这篇博客。希望大家在前端道路上。。嗯。。顺利是不希望我们顺利的  所以是披荆斩棘,佛挡杀佛,神挡杀神,与君共勉!



附言:有时间大家可以看看阮一峰大牛的网络日志,我刚看到最新更新的任正非的管理思想,浅薄理解到一个十几万员工的大公司的管理之道,最高层怎么思考问题,分享地址:任正非管理思想 - 阮一峰的网络日志

你可能感兴趣的:(2019-08-30 小谈promise(附源码))