Promise.prototype.finally 方法在 ES7 中的实现

· 约 5 分钟读完

在 JavaScript 中,Promise 是一种用于异步编程的技术,它可以有效地解决回调地狱的问题,简化异步代码的编写。然而,在使用 Promise 进行异步编程时,我们经常会遇到一些副作用(side effect)的问题,例如无法正确处理错误、无法释放资源等。为了解决这些问题,ES7 中引入了 Promise.prototype.finally 方法,本文将介绍该方法的实现原理、使用方法以及相关注意事项。

Promise.prototype.finally 方法的实现原理

Promise.prototype.finally 方法用于指定一个函数,该函数在 Promise 结束时无论成功还是失败都会被调用。例如:

在 ES6 中,我们可以通过 Promise.prototype.then 和 Promise.prototype.catch 方法实现类似的效果,例如:

然而,这种方式存在一些问题。首先,我们需要在多个 then 方法中重复编写 finally 的逻辑,导致代码重复。其次,如果 finally 方法中抛出了异常,该异常将被忽略,无法正确处理错误。

为了解决这些问题,ES7 中引入了 Promise.prototype.finally 方法。该方法的实现原理如下:

该方法接受一个回调函数作为参数,返回一个新的 Promise 对象。在该 Promise 对象的 then 方法中,我们使用 this.constructor.resolve 方法生成一个新的 Promise 对象,该对象的 then 方法中调用回调函数,并在回调函数执行完成后返回原始的 Promise 对象。如果原始的 Promise 对象处于 rejected 状态,则在新的 Promise 对象的 then 方法中抛出原始的错误。

Promise.prototype.finally 方法的使用方法

使用 Promise.prototype.finally 方法非常简单,只需要在 Promise 对象的 then 方法之后调用 finally 方法,并传入一个回调函数即可。例如:

在上面的代码中,我们使用 fetch 方法异步获取数据,并对返回的数据进行处理。无论成功还是失败,finally 方法中的代码都会被执行。

Promise.prototype.finally 方法的注意事项

在使用 Promise.prototype.finally 方法时,需要注意以下几点:

  1. finally 方法返回一个新的 Promise 对象,而不是原始的 Promise 对象。因此,在 finally 方法之后调用的 then 方法并不会接收到原始的 Promise 对象。如果需要继续处理原始的 Promise 对象,可以在 finally 方法之前调用 then 方法,并将结果传递给 finally 方法。

  2. finally 方法中的回调函数不接收任何参数。如果需要在回调函数中访问 Promise 对象的返回值或错误信息,可以在 finally 方法之前调用 then 方法,并将结果传递给 finally 方法。

  3. finally 方法中的回调函数不能改变 Promise 对象的状态。如果回调函数返回一个新的 Promise 对象,则该 Promise 对象会覆盖原始的 Promise 对象,导致后续的 then 方法无法正确处理结果。

示例代码

下面是一个使用 Promise.prototype.finally 方法的示例代码:

在上面的代码中,我们定义了一个 fetchData 函数,该函数使用 fetch 方法异步获取数据,并对返回的数据进行处理。无论成功还是失败,finally 方法中的代码都会被执行。在 fetchData 函数之后,我们调用 then 方法对返回值进行处理,并调用 catch 方法处理错误信息。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d0d24de46428fe9ee35cff