在编写异步代码时,我们常常需要保证多个异步任务执行完成后才能进行下一步操作,这时就可以利用 ES6 中的 Promise.race 和 Promise.all 方法来实现。
Promise.race
Promise.race 接收一个由 Promise 对象组成的数组作为参数,执行时只要其中有一个 Promise 对象完成状态改变(不论是成功还是失败),就会进入相应的回调函数,返回一个新的 Promise 对象。
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'result1')); const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'result2')); const promise3 = new Promise((resolve, reject) => setTimeout(reject, 500, 'error3')); Promise.race([promise1, promise2, promise3]) .then(result => console.log(result)) // result1 .catch(error => console.log(error)); // 不会执行
在上述例子中,由于 promise1 在1秒后状态改变,promise2 是2秒后完成,promise3 在0.5秒后失败,所以 Promise.race 方法直接返回 promise1 的结果。
Promise.all
Promise.all 可以将多个 Promise 对象组合成一个新的 Promise 对象,只有所有 Promise 对象都变为 fulfilled 状态(即全部执行成功),才会进入成功的回调函数并返回一个包含所有 Promise 结果的数组。如果其中任意一个 Promise 对象变为 rejected 状态,则会进入失败的回调函数。
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'result1')); const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'result2')); const promise3 = new Promise((resolve, reject) => setTimeout(reject, 500, 'error3')); Promise.all([promise1, promise2, promise3]) .then(result => console.log(result)) .catch(error => console.log(error)); // error3
在上述例子中,由于 promise3 在0.5秒后失败,所以 Promise.all 方法直接返回失败回调,不会再等待其他 Promise 对象的状态改变。
Promise.race 和 Promise.all 的应用
Promise.race 和 Promise.all 在实际应用中有很大的用处,比如可以使用 Promise.race 来设置请求超时时间:
const timeout = new Promise((resolve, reject) => setTimeout(() => reject('timeout'), 1000)); const fetchData = fetch('https://example.com/data'); Promise.race([fetchData, timeout]) .then(result => console.log(result)) .catch(error => console.log(error)); // timeout
在上述例子中,由于 fetchData 完成时间超过1秒,timeout 直接返回失败回调,实现了请求超时的功能。
而 Promise.all 则可以用来批量发起请求并等待所有请求完成后作出相应:
const requestList = ['https://example.com/data1', 'https://example.com/data2', 'https://example.com/data3'].map(url => fetch(url)); Promise.all(requestList) .then(results => console.log(results)) .catch(error => console.log(error));
在上述例子中,将请求链接数组通过 map 方法转化为 Promise,再用 Promise.all 集成为一个 Promise 对象,等待所有请求完成后作出相应。
结语
Promise.race 和 Promise.all 方法可以使异步代码更加简单和优雅,应用广泛。但需要注意的是,在使用时需确保操作的正确性和执行效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c6f03dcc0f7239cde6816c