欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自己写一个Promise

程序员文章站 2022-07-02 17:02:12
参考Promise 的 官方规范 https://promisesaplus.com/ Promise 其实就是一个状态机 它只有两种状态变化 pending =》 fulfilled pending =》 rejected 并且状态一旦发生变化后就不会再改变 我们用es5来实现下 先写个架子, 并 ......

参考promise 的  官方规范  

promise 其实就是一个状态机

它只有两种状态变化 pending    =》   fulfilled

         pending    =》   rejected

并且状态一旦发生变化后就不会再改变

我们用es5来实现下

先写个架子, 并测试下:

function mypromise(executor) {
    var _this = this; // 保存当前的函数上下文
    _this.status = 'pending'; // 初始状态
    _this.resolvevalue = null;  // resolve初始值
    _this.rejectvalue = null;  // reject初始值
    function resolve(value) {
        if (_this.status ==  'pending') {
            _this.status = 'fulfilled';
            _this.resolvevalue = value;
        }
    }
    function reject(reason) {
        if (_this.status ==  'pending') {
            _this.status = 'fulfilled';
            _this.rejectvalue = reason;
        }
    }
    try {    // 捕获错误
        executor(resolve, reject)
    } catch (e){
        reject(e);
    }
}
mypromise.prototype.then = function (onfulfilled, onrejected) {
    var _this = this;
    if (_this.status == 'fulfilled') {
        onfulfilled(_this.resolvevalue)
    }
    if (_this.status == 'rejected') {
        onrejected(_this.rejectvalue)
    }
};

var p = new mypromise((resolve, reject) => {
    resolve('i am handsome');
    throw error('捕获错误')
});
p.then((data) => {
    console.log(data)
}, (err) => {
    console.log(err)
} );

结果:

自己写一个Promise

它先执行resolve   状态 变为   fulfilled    ,

然后报错 ,执行reject , 由于此时状态不是pending, 状态还是fulfilled

promise的核心是处理异步,

现在我们的代码并不能等待状态的改变,

接下来我们加上处理异步操作的功能, 并测试下

function mypromise(executor) {
    var _this = this; // 保存当前的函数上下文
    _this.status = 'pending'; // 初始状态
    _this.resolvevalue = null;  // resolve初始值
    _this.rejectvalue = null;  // reject初始值
    _this.resolvecallbacklist = []; // 存resolve的回调
    _this.rejectcallbacklist = []; // 存reject的回调
    function resolve(value) {
        if (_this.status ==  'pending') {
            _this.status = 'fulfilled';
            _this.resolvevalue = value;
            // 状态改变执行存的回调
            _this.resolvecallbacklist.foreach(function(ele){
                if (ele) {
                    ele();
                }
            })
        }
    }
    function reject(reason) {
        if (_this.status ==  'pending') {
            _this.status = 'rejected';
            _this.rejectvalue = reason;
            // 状态改变执行存的回调
            _this.rejectcallbacklist.foreach(function(ele){
                if (ele) {
                    ele();
                }
            })
        }
    }
    try {    // 捕获错误
        executor(resolve, reject)
    } catch (e){
        reject(e);
    }
}
mypromise.prototype.then = function (onfulfilled, onrejected) {
    var _this = this;
    if (_this.status == 'fulfilled') {
        onfulfilled(_this.resolvevalue)
    }
    if (_this.status == 'rejected') {
        onrejected(_this.rejectvalue)
    }
    // 等待状态时把回调存起来,状态改变再触发
    if (_this.status == 'pending') {
        _this.resolvecallbacklist.push(function () {
            onfulfilled(_this.resolvevalue)
        });
        _this.rejectcallbacklist.push(function () {
            onrejected(_this.rejectvalue)
        });
    }
};

var p = new mypromise((resolve, reject) => {
    settimeout(() => {
        resolve('i am handsome');
    }, 0);
    // throw error('捕获错误')
});
p.then((data) => {
    console.log(data)
}, (err) => {
    console.log(err)
} );

结果:

自己写一个Promise