回顾一下红宝书第四版P330中的一句话:”传给then()的任何非函数类型的参数都会被静默忽略“,这个忽略是单纯的忽略吗?其实不然,应该考虑到值穿透的问题
.then
或者 .catch
的参数期望是函数,传入非函数则会发生值穿透
举例1:
1 2 3 4 5 6 Promise .resolve (1 ) .then (2 ) .then (Promise .resolve (3 )) .then (console .log )
举例2:
1 2 3 4 5 6 7 Promise .resolve ('foo' ) .then (Promise .resolve ('bar' )) .then (function (res ) { console .log (res); })
举例3:
1 2 3 4 5 6 Promise .resolve (1 ) .then (function ( ) {return 2 }) .then (Promise .resolve (3 )) .then (console .log )
举例4:
1 2 3 4 5 6 7 8 Promise .resolve (1 ) .then (function ( ) {return 2 }) .then (function ( ) {return Promise .resolve (3 )}) .then (console .log )
拓展 :catch的穿透
举例1:一个很容易理解的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 new Promise ((resolve, reject ) => { reject (1 ) }) .then (value => { console .log ('success' , value); }, reason => { console .log ('failture' , reason); }) .then (value => { console .log ('success' , value); }, reason => { console .log ('failture' , reason); })
举例2:增加catch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 new Promise ((resolve, reject ) => { reject (1 ) }) .then (value => { console .log ('success' , value); }, reason => { console .log ('failture' , reason); }) .then (value => { console .log ('success' , value); }, reason => { console .log ('failture' , reason); }) .catch (reason => { console .log ('failture' , reason); })
举例3:then里面没有onRejected处理程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 new Promise ((resolve, reject ) => { reject (1 ); }) .then (value => { console .log ('success' , value); }) .then (value => { console .log ('success' , value); }) .catch (reason => { console .log ('failture' , reason); })
举例4:在举例3上拓展,注意看变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 new Promise ((resolve, reject ) => { reject (1 ); }) .then (value => { console .log ('success' , value); }) .then (value => { console .log ('success' , value); }, reason => { console .log ('failture111' , reason); }) .catch (reason => { console .log ('failture' , reason); })
举例5:当一个promise是reject状态,但是没有失败回调,也没有写catch捕获,那么系统会默认捕获
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 new Promise ((resolve, reject ) => { reject (1 ); }) .then (value => { console .log ('success' , value); }) .then (value => { console .log ('success' , value); })
等价代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 new Promise ((resolve, reject ) => { reject (1 ); }) .then (value => { console .log ('success' , value); }) .then (value => { console .log ('success' , value); }) .catch (reason => {throw reason});
总结
当使用.catch
时,会默认为没有指定失败回调函数的.then
添加一个失败回调函数【举例3,4】
.catch
所谓的值穿透并不是一个失败状态就触发.catch
,而是一层层传递下来的【举例3,5】
异常穿透的前提是所有.then都没有执行失败状态的回调函数【举例3,5】
如果.catch
前所有的.then
都制定了失败状态的回调函数,.catch
就失去了意义【举例2,4】
参考 Promise 值穿透 特性