Promise 值穿透 特性

今天看promise相关知识,发现值穿透这个特性之前并不太了解,特此记录一下

代码:

Promise.resolve(1)
      .then(2) // 注意这里
      .then(Promise.resolve(3))
      .then(console.log)
此代码输出结果是1

再看下面代码:

Promise.resolve('foo')
    .then(Promise.resolve('bar'))
    .then(function(result){
      console.log(result)
    })
此代码输出'foo'

继续看下面代码

Promise.resolve(1)
  .then(function(){return 2})
  .then(Promise.resolve(3))
  .then(console.log)

输出2,没问题

最后一个例子

Promise.resolve(1)
  .then(function(){return 2})
  .then(function(){return Promise.resolve(3)})
  .then(console.log)

输出3

解释:.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。

补充一点:再继续看一下catch的穿透

代码1

new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value);
      }, reason => {
        console.log('失败', reason); //失败 1;无返回值、默认返回成功状态,状态值为undefined
      })
      .then(value => {
        console.log('成功', value); //成功 undefined
      }, reason => {
        console.log('失败', reason);
      })

第一个then接受了两个函数,第二个是失败时候的回调,由于第一个then里面没有抛出Error,则第二个then状态是resolve

第二个例子

new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value);
      }, reason => {
        console.log('失败', reason); //失败 1;无返回值、默认返回成功状态,状态值为undefined
      })
      .then(value => {
        console.log('成功', value); //成功 undefined
      }, reason => {
        console.log('失败', reason);
      })
      .catch(reason => console.log('失败', reason)) //这里增加catch,但是不会走到这里来

第三个例子

 new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value); //没有指定失败的回调函数,不执行代码,去往下一级寻找失败状态回调函数
      })
      .then(value => {
        console.log('成功', value); //没有指定失败的回调函数,不执行代码,去往下一级寻找失败状态回调函数
      })
      .catch(reason => console.log('失败', reason))  //这里执行了,失败 1;
    //打印结果
    //失败 1;

    //当then方法中没有指定失败的回调函数时,
    //使用.catch会默认为没有指定失败回调函数的.then指定失败回调函数为:
    reason => {
      throw reason //注意不是return reason 而是throw reason ;throw保证了返回结果为失败
    }

结论:使用.catch会默认为没有指定失败回调函数的.then指定失败回调函数为:

第四个例子

new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value); //没有指定失败的回调函数,不执行代码,去往下一个.then
      })
      .then(value => {
        console.log('成功', value);
      }, reason => {               //指定失败的回调函数,执行失败的回调函数,没有调用catch
        console.log('失败hhhhh', reason);
      })
      .catch(reason => console.log('失败', reason))
    //打印结果
    //失败hhhhh  1;
    
	//使用.catch会默认为没有指定失败回调函数的.then指定失败回调函数为:
    reason => {
      throw reason //注意不是return reason 而是throw reason ;throw保证了返回结果为失败
    }

结论:当一个promise是reject状态,但是没有失败回调,也没有写catch捕获,那么系统会默认捕获,捕获形式如下所示:

reason => {
      throw reason //注意不是return reason 而是throw reason ;throw保证了返回结果为失败
    }

也就是下面的代码:

new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value);
      })
      .then(value => {
        console.log('成功', value); //成功 undefined
      })

跟下面的代码是一样的:(注意看最后一行)

new Promise((resolve, reject) => {
        reject(1) //失败状态
      })
      .then(value => {
        console.log('成功', value);
      })
      .then(value => {
        console.log('成功', value); //成功 undefined
      })
      .catch(reson => {throw reson})

总结:当使用.catch时,会默认为没有指定失败状态回调函数的.then添加一个失败回调函数(上文中有具体函数代码)。 .catch所谓的异常穿透并不是一次失败状态就触发catch,而是一层一层的传递下来的。 异常穿透的前提条件是所有的.then都没有指定失败状态的回调函数。 如果.catch前的所有.then都指定了失败状态的回调函数,.catch就失去了意义。

如果哪里写的不对,欢迎留言交流,一起沟通

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值