ECMAScript 2019 中的 Promise.all 和 Promise.race 方法详解
在前端开发中,异步编程是一项非常重要的技能。而 Promise 是一种用于异步编程的解决方案,它可以避免回调地狱,使代码更加简洁。在 ECMAScript 2015 中,Promise 被引入了标准库,并在 ECMAScript 2019 中新增了两个方法:Promise.all 和 Promise.race。本文将详细介绍这两个方法的使用方法和指导意义,以及提供示例代码。
Promise.all
Promise.all 方法接受一个数组作为参数,数组中的每个元素都是一个 Promise 对象。当数组中的所有 Promise 对象都变为 resolved 状态时,Promise.all 方法才会返回一个新的 Promise 对象,其状态为 resolved。这个新的 Promise 对象的值是一个数组,其中包含了每个 Promise 对象的 resolved 值,数组的顺序与原数组的顺序相同。
如果数组中的任意一个 Promise 对象变为 rejected 状态,Promise.all 方法会立即返回一个新的 Promise 对象,其状态为 rejected,其值是第一个变为 rejected 状态的 Promise 对象的 reason 值。
下面是 Promise.all 方法的基本使用方法:
const promise1 = Promise.resolve(1); const promise2 = Promise.resolve(2); const promise3 = Promise.resolve(3); Promise.all([promise1, promise2, promise3]) .then(values => { console.log(values); // [1, 2, 3] });
在上面的例子中,我们创建了三个 Promise 对象,并使用 Promise.all 方法将它们组合在一起。当这三个 Promise 对象都变为 resolved 状态时,Promise.all 方法返回一个新的 Promise 对象,并将 resolved 值的数组作为参数传递给 then 方法。
如果其中一个 Promise 对象变为 rejected 状态,Promise.all 方法会立即返回一个新的 Promise 对象,并将 rejected 值作为参数传递给 catch 方法。例如:
// javascriptcn.com 代码示例 const promise1 = Promise.resolve(1); const promise2 = Promise.reject('error'); const promise3 = Promise.resolve(3); Promise.all([promise1, promise2, promise3]) .then(values => { console.log(values); }) .catch(error => { console.log(error); // 'error' });
在上面的例子中,我们故意将第二个 Promise 对象设置为 rejected 状态。当 Promise.all 方法检测到有一个 Promise 对象变为 rejected 状态时,就会立即返回一个新的 Promise 对象,并将 rejected 值作为参数传递给 catch 方法。
Promise.race
Promise.race 方法接受一个数组作为参数,数组中的每个元素都是一个 Promise 对象。当数组中的任意一个 Promise 对象变为 resolved 或 rejected 状态时,Promise.race 方法就会返回一个新的 Promise 对象,并将第一个变为 resolved 或 rejected 状态的 Promise 对象的值作为新 Promise 对象的值。
下面是 Promise.race 方法的基本使用方法:
// javascriptcn.com 代码示例 const promise1 = new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { reject('rejected'); }, 2000); }); Promise.race([promise1, promise2]) .then(value => { console.log(value); // 'resolved' }) .catch(reason => { console.log(reason); // 'rejected' });
在上面的例子中,我们创建了两个 Promise 对象,其中一个是在 1 秒后变为 resolved 状态,另一个是在 2 秒后变为 rejected 状态。当 Promise.race 方法检测到 promise1 变为 resolved 状态时,就会返回一个新的 Promise 对象,并将 resolved 值作为新 Promise 对象的值。由于 promise2 变为 rejected 状态的时间比 promise1 慢,所以其值不会被用于新 Promise 对象的值。
指导意义
Promise.all 和 Promise.race 方法是在异步编程中非常有用的工具。它们可以帮助我们更好地处理异步操作的结果,并避免回调地狱。使用 Promise.all 方法可以将多个异步操作组合在一起,等待它们全部完成后再进行下一步操作。使用 Promise.race 方法可以在多个异步操作中选择最先完成的操作,并根据其结果进行下一步操作。
需要注意的是,在使用 Promise.all 方法时,如果数组中的某个 Promise 对象永远处于 pending 状态,那么 Promise.all 方法就会一直等待,不会返回任何结果。因此,我们需要确保所有的异步操作都能够正常完成,或者在一定时间内完成。
示例代码
下面是一个使用 Promise.all 和 Promise.race 方法的示例代码,用于获取多个网站的响应时间,并显示最快和最慢的响应时间:
// javascriptcn.com 代码示例 const urls = [ 'https://www.google.com', 'https://www.baidu.com', 'https://www.github.com' ]; const requests = urls.map(url => { const start = Date.now(); return fetch(url) .then(() => { const end = Date.now(); return end - start; }); }); Promise.all(requests) .then(times => { const fastest = Math.min(...times); const slowest = Math.max(...times); console.log(`Fastest response time: ${fastest}ms`); console.log(`Slowest response time: ${slowest}ms`); }) .catch(error => { console.log(error); }); Promise.race(requests) .then(time => { console.log(`Fastest response time: ${time}ms`); }) .catch(error => { console.log(error); });
在上面的示例代码中,我们首先定义了一个包含多个网站 URL 的数组。然后,我们使用数组的 map 方法将每个 URL 转换为一个 Promise 对象,该 Promise 对象在完成后返回该网站的响应时间。最后,我们同时使用 Promise.all 和 Promise.race 方法来获取最快和最慢的响应时间,并将其输出到控制台上。
总结
在 ECMAScript 2019 中,Promise.all 和 Promise.race 方法为异步编程提供了更加强大的工具。它们可以帮助我们更好地处理异步操作的结果,并避免回调地狱。使用 Promise.all 方法可以将多个异步操作组合在一起,等待它们全部完成后再进行下一步操作。使用 Promise.race 方法可以在多个异步操作中选择最先完成的操作,并根据其结果进行下一步操作。我们需要注意的是,在使用这两个方法时,需要确保所有的异步操作都能够正常完成,或者在一定时间内完成。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/656143ded2f5e1655db57fa5