在 ECMAScript 2019 中,Promise 对象新增了两个方法:Promise.all() 和 Promise.allSettled()。这两个方法都是用来处理多个 Promise 对象的,但是它们的行为有所不同。本文将会详细介绍这两个方法的用法、差异以及实际应用。
Promise.all()
Promise.all() 方法接收一个可迭代对象(如数组),并返回一个新的 Promise 对象。这个新的 Promise 对象在传入的所有 Promise 对象都成功(即状态变为 resolved)后才会变为成功状态,且返回值是一个按照传入顺序排列的 Promise 对象的返回值数组。如果有任何一个 Promise 对象失败(即状态变为 rejected),则新的 Promise 对象会立即变为失败状态,并返回第一个失败的 Promise 对象的错误信息。
示例代码:
// javascriptcn.com 代码示例 const promises = [ Promise.resolve('foo'), Promise.resolve('bar'), Promise.resolve('baz') ]; Promise.all(promises) .then(results => console.log(results)) // ['foo', 'bar', 'baz'] .catch(error => console.error(error)); const promises2 = [ Promise.resolve('foo'), Promise.reject(new Error('bar')), Promise.resolve('baz') ]; Promise.all(promises2) .then(results => console.log(results)) .catch(error => console.error(error)); // Error: bar
在上面的示例代码中,第一个 Promise.all() 的调用成功地返回了一个包含三个字符串的数组,因为传入的所有 Promise 对象都成功了。而第二个 Promise.all() 的调用则失败了,因为第二个 Promise 对象被拒绝了,因此新的 Promise 对象也被拒绝了,并返回了第二个 Promise 对象的错误信息。
Promise.allSettled()
Promise.allSettled() 方法与 Promise.all() 方法类似,也接收一个可迭代对象,并返回一个新的 Promise 对象。不同的是,新的 Promise 对象在传入的所有 Promise 对象都完成(即状态变为 resolved 或 rejected)后才会变为成功状态,且返回值是一个按照传入顺序排列的对象数组,每个对象都包含了对应 Promise 对象的状态和返回值/错误信息。
示例代码:
// javascriptcn.com 代码示例 const promises = [ Promise.resolve('foo'), Promise.reject(new Error('bar')), Promise.resolve('baz') ]; Promise.allSettled(promises) .then(results => console.log(results)) .catch(error => console.error(error)); /* [ { status: 'fulfilled', value: 'foo' }, { status: 'rejected', reason: Error: bar }, { status: 'fulfilled', value: 'baz' } ] */
在上面的示例代码中,Promise.allSettled() 的调用返回了一个包含三个对象的数组,每个对象都包含了对应 Promise 对象的状态和返回值/错误信息。即使第二个 Promise 对象被拒绝了,新的 Promise 对象仍然成功地返回了所有 Promise 对象的状态和返回值/错误信息。
应用场景
Promise.all() 和 Promise.allSettled() 方法在实际应用中都有各自的优势。Promise.all() 方法通常用于在多个异步操作都成功完成后执行一些操作,如:
// javascriptcn.com 代码示例 const fetchUsers = () => { return fetch('https://jsonplaceholder.typicode.com/users') .then(response => response.json()); }; const fetchPosts = () => { return fetch('https://jsonplaceholder.typicode.com/posts') .then(response => response.json()); }; Promise.all([fetchUsers(), fetchPosts()]) .then(([users, posts]) => { console.log(users, posts); // do something with users and posts }) .catch(error => console.error(error));
上面的代码中,Promise.all() 方法用于在获取用户和帖子数据后执行一些操作。
Promise.allSettled() 方法则通常用于需要获取多个数据源的情况,即使其中某个数据源出现错误也需要获取其他数据源的数据,如:
// javascriptcn.com 代码示例 const fetchUsers = () => { return fetch('https://jsonplaceholder.typicode.com/users') .then(response => response.json()); }; const fetchPosts = () => { return fetch('https://jsonplaceholder.typicode.com/posts') .then(response => response.json()); }; const fetchComments = () => { return fetch('https://jsonplaceholder.typicode.com/comments') .then(response => response.json()); }; Promise.allSettled([fetchUsers(), fetchPosts(), fetchComments()]) .then(results => { const users = results[0].status === 'fulfilled' ? results[0].value : []; const posts = results[1].status === 'fulfilled' ? results[1].value : []; const comments = results[2].status === 'fulfilled' ? results[2].value : []; console.log(users, posts, comments); // do something with users, posts and comments }) .catch(error => console.error(error));
上面的代码中,Promise.allSettled() 方法用于获取用户、帖子和评论数据,即使其中某个数据源出现错误也仍然可以获取其他数据源的数据。
总结
Promise.all() 和 Promise.allSettled() 方法都是用来处理多个 Promise 对象的,但是它们的行为有所不同。Promise.all() 方法在传入的所有 Promise 对象都成功时才会成功,并返回一个按照传入顺序排列的 Promise 对象的返回值数组;而 Promise.allSettled() 方法则在传入的所有 Promise 对象都完成时才会成功,并返回一个按照传入顺序排列的对象数组,每个对象都包含了对应 Promise 对象的状态和返回值/错误信息。在实际应用中,我们可以根据具体的需求选择使用不同的方法来处理多个 Promise 对象。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6568ea12d2f5e1655d186081