JS中的Promise的then方法

Promise.prototype.then回调里面的返回值,是通过一个变量/私有API保存的,不是return出来的,想接收/包装返回值得在Promise状态完成了之后通知执行回调函数

我再简单的举例,一个简单的异步任务如何拿到值:

var foo = (callback) => {
    //通过回调函数拿值
    setTimeout(function () {
        callback(1);
    });
};

promise进行一下扁平化的封装

var Promise = function (callback) {
    if (!(this instanceof Promise)) {
        return new Promise(callback);
    }
    var $this = this;
    setTimeout(function () {
        callback(function (value) {
            //执行callback
            $this.callback(value);
        });
    });
}


Promise.prototype.then = function (resolveHandler) {
    this.callback = resolveHandler;
    return this;
};


Promise(function (resolve) {
    setTimeout(function () {
        resolve(1);
    }, 300)
}).then(function (value) {
    console.log(value);
});
//300ms后输出1

正常返回int,string类型都是比较好处理,而返回一个Promise该如何处理呢?—— 使用回调链啊

然后我把原回答的代码再次简化了一下,当然这个代码只能大概展现then对于返回值处理的原理,真正要完成Promise还有很多的细节处理

—————— 下面是原回答:

看了半天有点没太懂,在chrome dev跑了下代码发现你的代码报错了,导致了new Promise那里卡住了。

Promise.resolve(1).then(arg => {
    return new Promise(arg);//这里直接是new Promise(1),API不支持
}).then(arg => console.log(arg))

然后回答你后面的困惑,thenPromise返回值应该进行异步包装,并且仅依靠promise的公开API是无法实现then返回的包装的,需要一层链进行包装才可以。

简单的说就是:Promise.prototype.then中,正常的返回值,仅需要进行Promise一层包装即可,而Promise类型的返回值,则需要操作私有API进行回调链的包装,大概类似下面这样:


//为了例子简单点,只做一个resolveHandler
Promise.prototype.then = function(resolveHandler) {
    var promise = this;
    return new Promise((resolve, reject) => {
        var newPromise = this;
        setTimeout(function () {
            if (promise.status == 'pending') {//如果当前Promise的任务没有完成

                //如果已经有了回调函数onFulfilled,则再包装出回调链  => 这个回调函数要在Promise状态完成后执行
                if (promise.onFulfilled) {
                    //这里是重点,这里是重点,这里是重点,重要的事情说三遍
                    const oldOnFulfilled = promise.onFulfilled;
                    promise.onFulfilled = () => {
                        //进行链传递
                        var oldValue = oldOnFulfilled();
                        //如果上一个promise也返回了一个promise,则把当前的函数压入上一个promise链中
                        if (oldValue.___proto__ === Promise)
                            newPromise.onFulfilled = resolveHandler;
                        else
                            resolveHandler(oldValue);

                    };
                } else {
                    //没有回调函数,则压入回调函数
                    promise.onFulfilled = () => {
                        //传递返回值
                        resolveHandler(promise.result);
                    };
                }

            }
        });
    });

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值