剖析 Promise

34 篇文章 0 订阅
1 篇文章 0 订阅

最终实现的Promise代码,详细过程情况文章最后的原文链接。

// 例1
function getUserId() {
    return new Promise(function (resolve) {
        // 异步请求
        Y.io('/userid', {
            on: {
                success: function (id, res) {
                    resolve(JSON.parse(res).id);
                }
            }
        });
    });
}

function getUserMobileById(id) {
    return new Promise(function (resolve) {
        console.log('start to get user mobile by id:', id);
        Y.io('/usermobile/' + id, {
            on: {
                success: function (i, o) {
                    resolve(JSON.parse(o).mobile);
                }
            }
        });
    });
}

getUserId().then(getUserMobileById).then(function (mobile) {
    // do sth with mobile
});

//------------

function Promse(fn) {

    var state = 'pending',
        value = null,
        deferreds = [];

    this.then = function(onFulfilled, onRejected) {

        return new Promse(function (resolve, reject) {
             handle({
                onFulfilled: onFulfilled || null,
                onRejected: onRejected || null,
                resolve: resolve,
                reject: reject,
             })
        });
        //resolve执行后,then添加的新回调都会立即执行
        //处理即一个Promise后带多个then情况
        // if (state == 'pending') {
        //     deferreds.push(onFulfilled);
        //     return this;
        // }
        // onFulfilled(value);
        // return this;
    }
    
    function handle(deferred) {

        if (state === 'pending') {
            deferreds.push(deferred);
            return;
        }
        var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected,
            ret;

        if (cb === null) {
            cb = state === 'fulfilled' ? deferred.resolve : deferred.reject;
            cb(value);
            return;
        }

        try {
            ret = cb(value);
            deferred.resolve(ret);
        } catch (e) {
            deferred.reject(e);
        }      
    }

    function resolve(newValue) {       
        
        if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
            var then = newValue.then;
            if (typeof then === 'function') {
                then.call(newValue, resolve, reject);
                return;
            }
        }

        //通过setTimeout将resolve中执行回调的逻辑放置到JS任务队列末尾
        //当fn中为同步操作时强制resolve异步
        //即先执行后续的then再调用resolve        
        value = newValue;
        state = 'fulfilled'; //resolve执行时,将状态设置为fulfilled
        setTimeout(function () { 
            deferreds.forEach(function (deferred) {
                deferred(value);
            })
        },0);       
    }

    function reject(newValue) {
        state = 'rejected';
        value = newValue;
        setTimeout(function () { 
            deferreds.forEach(function (deferred) {
                deferred(value);
            })
        },0); 
    }

    fn(resolve, reject);
}

转载美团点评技术团队关于Promise的一篇文章,将的挺仔细的,值得学习啊。

链接地址: https://tech.meituan.com/techsalon

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值