自己写一个Promise - Go语言中文社区

自己写一个Promise


参考Promise 的  官方规范  https://promisesaplus.com/

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)
} );

结果:

它先执行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)
} );

结果:

 

 

版权声明:本文来源博客园,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.cnblogs.com/LHLVS/p/10796751.html
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-11-17 16:59:18
  • 阅读 ( 1350 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢