随着 JavaScript 前端技术的发展,异步编程方法变得越来越普及,Promise 已成为一种常用的处理异步操作的方式。在 ES10 之后,Promise 中引入了三个新的方法:Promise.all()、Promise.race() 和 Promise.allSettled(),它们向异步编程提供了更加灵活的解决方案。
本文将分别介绍这三个方法的用法、示例和特点,并从优劣和应用场景两个角度进行比较,帮助开发者更好地理解和使用这些方法。
Promise.all()
Promise.all() 可以将多个 Promise 实例包装成一个新的 Promise 实例,返回值是一个数组,数组中的值即为每个 Promise 实例的返回值。当这些 Promise 实例都成功时,返回的新 Promise 实例才算成功,其中只要有一个 Promise 实例失败,则新 Promise 实例就会失败。
示例代码:
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] }); const promise4 = new Promise((resolve, reject) => { setTimeout(() => { resolve('four'); }, 2000); }); Promise.all([promise1, promise4]).then(values => { console.log(values); // 这行代码不会执行 }).catch(error => { console.error(error); // 输出: "four" (在两秒后) });
注:Promise.all() 方法有一个特殊的行为,即在传入的 Promise 实例数组中有非 Promise 实例时,会自动将其转化为 Promise 实例。
Promise.race()
Promise.race() 方法的用法和 Promise.all() 类似,都是将多个 Promise 包装成一个新的 Promise 实例。不同的是,Promise.race() 的新 Promise 实例的状态是由数组中最先发生变化的 Promise 实例的状态决定的。也就是说,只要有一个 Promise 实例率先被成功或失败,新的 Promise 实例就会采用这个 Promise 实例的返回值或错误原因作为自己的返回值或错误原因。
示例代码:
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise1'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { reject('error from promise2'); }, 500); }); Promise.race([promise1, promise2]).then(value => { console.log(value); // 输出 "promise1" (在一秒后) }).catch(error => { console.error(error); // 输出 "error from promise2" (在0.5秒后) });
Promise.allSettled()
Promise.allSettled() 方法不同于 Promise.all() 和 Promise.race(),它的新 Promise 实例即使有 Promise 实例状态是失败的,也不会抛出错误,而是循序渐进地执行每个 Promise 实例,并在所有 Promise 实例都返回后返回一个包含各 Promise 结果状态的对象数组。
示例代码:
const promise1 = Promise.resolve(1); const promise2 = Promise.reject('rejected'); const promise3 = Promise.resolve(3); Promise.allSettled([promise1, promise2, promise3]).then(results => { console.log(results); // 输出 [ { status: "fulfilled", value: 1 }, // { status: "rejected", reason: "rejected" }, // { status: "fulfilled", value: 3 } ] });
比较
优劣
三个方法的结果类型不同,Promise.all() 在所有 Promise 实例成功时返回数组类型结果,当有一个 Promise 实例失败时则直接抛出错误;Promise.race() 和 Promise.allSettled() 在任意一个 Promise 实例成功或失败时都会进行相应的处理,不会直接抛出错误。从结果类型和异常处理方面来看,Promise.race() 和 Promise.allSettled() 更加灵活,适用范围更广。
应用场景
- Promise.all(),适用于需要同时对多个可并行执行的异步任务进行控制,通常会在多个请求完毕后整合请求的结果使用。
- Promise.race(),适用于只关心最先执行完毕的异步任务的结果,例如请求中有多个接口地址,只要有一个接口返回数据就可以使用,忽略其他的请求。
- Promise.allSettled(),适用于一些极端的场景,需要了解所有 Promise 实例的执行情况,并忽略 Promise 实例的状态。
总结
Promise.all()、Promise.race() 和 Promise.allSettled() 这三个方法在 ES6 异步编程中具有重要的作用,新方法的引入使得 Promise 更加灵活多变,开发者可以根据自己的需求来选择使用其中的某一种或多种方式。在实际开发中,我们可以根据自己的实际需求来灵活应用这些方法,提高异步编程的效率,避免冗余的代码,从而更好地完成项目开发。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b20027add4f0e0ffb2f46e