Promise运行原理

更详细的解释请点击:https://blog.csdn.net/weixin_41817034/article/details/80492315

面试精选之Promise:https://blog.csdn.net/weixin_42367621/article/details/80824277

1.什么是Promise
Promise可以认为是一种用来解决异步处理的代码规范。常见的异步处理是使用回调函数,回调函数有两种模式,同步的回调和异步的回调。一般回调函数指的是异步的回调。

同步回调

function add(a, b, callback) { callback(a + b) }
        
        console.log('before');
        add(1, 2, result => console.log('Result: ' + result);
        console.log('after');

输出结果为: before Result:3 after

异步回调

function addAsync(a, b, callback) {
        setTimeout( () => callback(a + b), 1000);
    }

    console.log('before');
    addAsync(1, 2, result => console.log('Result: ' + result));
    console.log('after');

输出结果: before after Result: 3

然而回调函数有个著名的坑就是“callback hell”,比如:

    doSomething1(function(value1) {
        doSomething2(function(value2) {
            doSomething3(function(value3) {
                console.log("done! The values are: " + [value1, value2, value3].join(','));
            })
        })
    })

为了等value1, value2, value3数据都准备好,必须要一层一层嵌套回调函数。如果一直嵌套下去,就形成了callback hell,不利于代码的阅读。

如果改用Promise的写法,只要写成如下方式就行。

    doSomething1().then(function() {
        return value1;
    }).then(function(tempValue1) {
        return [tempValue1, value2].join(',');      
    }).then(function(tempValue2) {
        console.log("done! ", [tempValue2, value3].join(','));
    });

可以注意到,Promise实际上是把回调函数从doSomething函数中提取到了后面的then方法里面,从而防止多重嵌套的问题。

2.Promise对象和状态

2.1 resolve & reject

Promise构造函数用来构造一个Promise对象,其中入参匿名函数中resolve和reject这两个也都是函数。如果resolve执行了,则触发promise.then中成功的回调函数;如果reject执行了,则触发promise.then中拒绝的回调函数。

    var promise = new Promise(function(resolve, reject) {
        // IF 如果符合预期条件,调用resolve
        resolve('success');

        // ELSE 如果不符合预期条件,调用reject
        reject('failure')
    })

2.2 Fulfilled & Rejected
Promise对象一开始的值是Pending准备状态。
执行了resolve()后,该Promise对象的状态值变为onFulfilled状态。
执行了reject()后,该Promise对象的状态值变为onRejected状态。
Promise对象的状态值一旦确定(onFulfilled或onRejected),就不会再改变。即不会从onFulfilled转为onRejected,或者从onRejected转为onFulfilled。
2.3 快捷方法
获取一个onFulfilled状态的Promise对象:

Promise.resolve(1);

// 等价于

new Promise((resolve) => resolve(1));

获取一个onRejected状态的Promise对象:

Promise.reject(new Error("BOOM")) 

// 等价于

new Promise((resolve, reject) 
    => reject(new Error("BOOM")));

3.异常捕获:then和catch

Promise的异常捕获有两种方式:

then匿名函数中的reject方法
catch方法
3.1 then中的reject方法捕获异常

这种方法只能捕获前一个Promise对象中的异常,即调用then函数的Promise对象中出现的异常。

    var promise = Promise.resolve();

    promise.then(function() {
        throw new Error("BOOM!")
    }).then(function (success) {
        console.log(success);
    }, function (error) {
        // 捕捉的是第一个then返回的Promise对象的错误
        console.log(error);
    });

但该种方法无法捕捉当前Promise对象的异常,如:

    var promise = Promise.resolve();

    promise.then(function() {
        return 'success';
    }).then(function (success) {
        console.log(success);
        throw new Error("Another BOOM!");
    }, function (error) {
        console.log(error);  // 无法捕捉当前then中抛出的异常
    });

3.2 catch捕获异常

上述栗子若改写成如下形式,最后追加一个catch函数,则可以正常捕捉到异常。

    var promise = Promise.resolve();

    promise.then(function() {
        return 'success';
    }).then(function (success) {
        console.log(success);
        throw new Error("Another BOOM!");
    }).catch(function (error) {
        console.log(error); // 可以正常捕捉到异常
    });

catch方法可以捕获到then中抛出的错误,也能捕获前面Promise抛出的错误。 因此建议都通过catch方法捕捉异常。

    var promise = Promise.reject("BOOM!");

    promise.then(function() {
        return 'success';
    }).then(function (success) {
        console.log(success);
        throw new Error("Another BOOM!");
    }).catch(function (error) {
        console.log(error);  // BOOM!
    });

值得注意的是:catch方法其实等价于then(null, reject),上面可以写成:

    promise.then(function() {
        return 'success';
    }).then(function (success) {
        console.log(success);
        throw new Error("Another BOOM!");
    }).then(null, function(error) {
        console.log(error);
    })

总结来说就是:

  • 使用promise.then(onFulfilled, onRejected)的话,在 onFulfilled中发生异常的话,在onRejected中是捕获不到这个异常的。
  • 在promise.then(onFulfilled).catch(onRejected)的情况下then中产生的异常能在.catch中捕获
  • .then和 .catch在本质上是没有区别的需要分场合使用。


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值