ES2018中finally()和then()之间的差异

时间:2018-04-16 18:56:06

标签: javascript promise ecmascript-next

在ES2018之前,我曾经在承诺链的末尾嵌套了额外的then,每当我必须执行任何清理逻辑时,我会在then和{{{ 1}}以上,例如



catch




但是现在new Promise( (res, rej) => setTimeout(() => rej({}), 1000) ).then( res => console.log(res) ).catch( err => console.error(err) ).then( () => console.log('Finally') )原型上添加了finally,我无法看到它与上述方法中的上一个Promise有何不同。以下将产生相同的输出。



then




new Promise( (res, rej) => setTimeout(() => rej({}), 1000) ).then( res => console.log(res) ).catch( err => console.error(err) ).finally( () => console.log('Finally') )仅仅在本机Promise API中用于语义目的吗?

2 个答案:

答案 0 :(得分:5)

当承诺被拒绝时,then回调不会执行 - 即使对于catch调用返回的承诺,也可能发生这种情况:当其回调抛出或返回被拒绝的承诺时。 err => console.error(err) 可能不会这样做,但你永远不会知道。

同样,如果您只想处理原始承诺中的错误而不是then回调中的错误,我建议favour .then(…, …) over .then(…).catch(…)。我写了

promise.then(console.log, console.error).finally(() => console.log('Finally'));

其他more or less obvious差异在签名中:finally回调没有收到任何参数,p.finally()返回的承诺将以相同的结果实现/拒绝作为p(除非在回调中有异常或返回拒绝)。

答案 1 :(得分:1)

无论承诺是履行还是拒绝,

finally()都会执行。也许MDN doc的例子会有所帮助。

修改:MDN文档提供了与then()

的这些差异
  

finally()方法与调用.then(onFinally, onFinally)非常相似,但存在一些差异:

     
      
  • 创建内联函数时,可以传递一次,而不是强制要求它两次,或者为它创建一个变量
  •   
  • finally回调不会收到任何争论,因为没有可靠的方法来确定是否履行了承诺或   被拒绝。这个用例适用于您不关心的情况   拒绝原因,或履行价值,所以没有必要   提供它。
  •   
  • Promise.resolve(2).then(() => {}, () => {})不同(将使用undefined解决),Promise.resolve(2).finally(() => {})   将通过2解决。
  •   
  • 同样地,与Promise.reject(3).then(() => {}, () => {})不同(将使用undefined来实现),   Promise.reject(3).finally(() => {})将拒绝3
  •