实现Promise

Promise是将异步写法变为同步写法的规范
  
  只是写法的改变,操作并没有改变
    异步操作:在回调函数中,一层嵌套一层
    同步操作:将方法写在外部
  三个状态
    pending 表示操作正在执行
    resolved 表示操作执行成功
    rejected 表示操作执行失败
  状态的流向:在Promise中状态有两个方向的流动:
    状态由pending流向resolved, 说明操作执行成功完毕
    状态由pending流向rejected, 说明操作执行失败完毕
 
语法: new Promise((resolve, reject) => { 回调函数中执行异步操作 })
  如果操作执行成功 执行resolve方法 如果操作执行失败 执行reject方法
 
在外部通过then方法监听状态的改变
    then(success, fail)
该方法接收两个参数
  success: 表示成功时候执行的回调函数,参数是由 resolve方法执行的时候传递的参数(只能传递一个)
  fail:表示失败时候执行的回调函数,参数是由 reject方法执行的时候传递的参数(只能传递一个)
then方法的返回值是Promise对象,因此,可以链式调用该方法
  上一个then方法的输出,将作为下一个then方法参数的输入。如果操作已经执行完毕,then方法也会立即执行
 
实现Promise:
  
<script>
    // 构造函数
    function MyPromise(callback) {
        // 定义当前状态
        this.status = 'pending';
        // 定义成功时候的回调函数队列
        this.successArr = [];
        // 定义失败时候的回调函数队列
        this.failArr = [];

        // 实现成功时候执行的方法 resolve方法
        let resolve = value => {
        // this在普通函数中指向window 我们这里使用箭头函数 this的指向永远是定义时的 就解决了this的指向问题
       // 改变状态
            this.status = 'resolved';
            // 依次执行成功队列的方法
            this.successArr.forEach(fn => value = fn(value));
            // this.successArr.forEach(function(fn) {
            //     value = fn(value);
            // })
            // 将value存储在自身
            this.value = value;
            // 清空队列
            this.successArr = [];
        };

        // 实现失败时候执行的方法
        let reject = value => {
            // 更改状态
            this.status = 'rejected';
            // 执行回调函数
            this.failArr.forEach(fn => value = fn(value));
             // 将value存储在自身
            this.value = value;
            // 清空队列
            this.failArr = [];
        }

        // 执行回调函数
        try {
            callback(resolve, reject);
        } catch(e) {
            // 运行时出现了错误,也就失败了
            reject(e);
        }
    };

    // 原型then方法
    MyPromise.prototype.then = function(success, fail) {
        // 要是处于执行的pending状态,要存储回调函数
        // 判断状态
        if(this.status === 'pending') {
            // 存储 往成功回调函数队列中添加数据
            success && this.successArr.push(success);
            // 如果fail不是undnefined,我们再往失败回调函数队列中添加数据
            fail && this.failArr.push(fail);
        } else if(this.status === 'resolved') {
            // 立即执行,不需要存储
            success && success(this.value);
        } else {
            // 失败了
            fail && fail(this.value);
        };
        // 返回this
        return this;
    };

    // 创建promise对象
    let p = new MyPromise((resolve, reject) => {
        console.log('start');
        setTimeout(() => {
            // 如果成功执行resovle
            resolve('执行成功');
            // 如果失败执行reject
            // reject('执行失败');
        }, 1000);
    });

    // 监听结果
    p.then(
    (success) => {
        console.log('success', success);
        // 前一个then方法的返回值将作为后一个then方法的参数
        return '第一个监听执行成功then方法的返回值';
    }, 
    (fail) => {   
        console.log('fail', fail);
        return '第一个监听失败成功then方法的返回值';
    })
    // 链式调用
    .then((success) => {
        console.log(success);
        return '第er个监听执行成功then方法的返回值';
    },
    (fail) => {
        console.log(fail);
        return '第er个监听失败成功then方法的返回值';
    })
    .then((success) => {
        console.log(success);
        return '第三个监听执行成功then方法的返回值';
    },
    (fail) => {
        console.log(fail);
        return '第三个监听失败成功then方法的返回值';
    })
    </script>
原文地址:https://www.cnblogs.com/yess/p/13129951.html