ES9 为异步编程提供的新特性 ——Promise.finally() 函数

ES9 为异步编程提供的新特性 ——Promise.finally() 函数

在 Web 开发中,异步编程已经成为不可或缺的重要部分。然而,异步编程往往会引发一系列困扰,例如回调地狱、代码可读性的降低以及难以处理异步代码中的错误等问题。为了解决这些问题,Promise API 内置了几个方法来优化我们的异步编程体验,其中 ES9 新增的 Promise.finally() 函数可谓是异步编程的福音。

Promise.finally() 函数简介

Promise.finally() 函数是一个无参数无返回值的函数,该函数会在 Promise 对象的状态改变并返回一个新的 Promise 对象,当该 Promise 对象状态变为fulfilled 或者rejected 时,finally() 中指定的回调函数都会被执行。

Promise.finally() 函数的回调函数有以下特点:

  1. 不管前面的Promise.then() 或者 Promise.catch() 本身是否return,finally() 中指定的回调函数总是会被调用。

  2. finally() 中指定的回调函数可以接受到前面 Promise 的状态,该状态可以是 Promise resolve 的返回值或者 Promise reject 的返回值。

  3. finally() 函数可以起到 Promise 链串联的作用。

下面是 Promise.finally() 函数的示例代码:

let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("ok"), 2000); });

promise .then(result => console.log(result)) .catch(error => console.log(error)) .finally(() => console.log("Promise finished"));

// output: ok Promise finished

在上面的示例中,我们首先创建了一个 Promise 对象,并在 2 秒钟后 resolve。接着我们使用 then() 方法打印 resolve 的返回值。最后我们使用 finally() 方法在 promise 对象返回后打印 "Promise finished"。

Promise.finally() 函数的深入讨论

  1. 结合 Promise.all() 使用

当我们在使用 Promise.all() 方法时,如果其中的一个 Promise 对象出现了异常,其它 Promise 对象仍然会继续执行。此时可以使用 Promise.finally() 方法,指定异常处理的逻辑,以确保所有 Promise 对象都执行完毕。

下面是一个实际的示例代码:

let promises = [fetch('/api1'), fetch('/api2'), fetch('/api3')];

Promise.all(promises) .then(responses => { responses.forEach(response => console.log(response.json())) }) .catch(error => console.log(error)) .finally(() => console.log("All requests finished"));

// output: json object of api1, api2 and api3 All requests finished

上面的示例中,我们创建了一个数组,其中包含了三个请求。我们使用 Promise.all() 方法来打印所有请求返回的 JSON 数据。如果在执行某个请求时出现了错误,我们会在 catch() 中得到返回的异常信息,并使用 finally() 来保证所有的请求都已经执行完毕。

  1. 结合 try...catch...finally 使用

对于某些场景来说,我们往往需要在 Promise 过程中添加异常处理的逻辑。而 Promise.finally() 函数可以作为该过程的最后一个字段执行,被当做 try...catch...finally 中的 finally 处理。在 Promise.then() 和 Promise.catch() 后面添加 Promise.finally() 可以让我们将同一些逻辑应用到成功/失败的 Promise 处理,并且也能确保在所有情况下,最终的状态处理都能够正确地被执行。

下面是一个包含 try...catch...finally 的示例代码:

function getResource(resource) { const proxyUrl = 'https://cors-anywhere.herokuapp.com/'; const targetUrl = 'http://example.com/';

}

try { Promise.all([getResource('index.html'), getResource('404.html'), getResource('about.html')]) .then(responses => { responses.forEach(response => console.log(response)) }) .catch(error => console.log(error)) .finally(() => console.log("All Done!")); } catch (error) { console.error('Caught error: ', error.message); } finally { console.log('In finally block.'); }

// output: Response object for index.html, 404.html and about.html. Request for index.html finished. Request for 404.html finished. Request for about.html finished. All Done!

我们使用 try...catch..finally 语句块以及 Promise.all() 方法来执行多个异步请求。在资源获取过程中,我们使用了 Promise.finally() 函数来打印请求完成的消息。在整个异步代码块执行完毕后,我们使用 Promise.finally() 函数来打印异步请求执行状态信息,包括成功和失败两种情况。

总结

ES9 新增的 Promise.finally() 函数为异步编程提供了强大的灵活性,在使用 Promise API 进行异步编程时,对于异步请求和处理最终状态处理的各种情况,使用 Promise.finally() 函数可以让我们更轻松地实现代码的复用以及逻辑的统一处理,同时有效避免了回调地狱等问题。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b7651badd4f0e0ffff432f