什么是 Promise
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败及其结果值。简单地说,Promise是一个表示以后某个时候会生成的值的占位符。
Promise 是处理异步操作的非常有用的对象。
JavaScript 提供了一个帮助函数 Promise.all(promisesArrayOrIterable)
支持并行处理多个Promises,并且在一个聚合数组中获取结果值。我么一起来学习下Promise.all()是怎么工作的。
1.Promise.all()
Promise.all() 是内置的帮助函数能够接受promise数组,函数返回的格式如下:
const allPromise = Promise.all([promise1, promise2, ...]);
然后可以使用 then-able 语法提取Promise返回的值:
allPromise.then(values => { values; // [valueOfPromise1, valueOfPromise2, ...] }).catch(error => { error; // rejectReason of any first rejected promise });
或者使用async/await 语法:
try { const values = await allPromise; values; // [valueOfPromise1, valueOfPromise2, ...] } catch (error) { error; // rejectReason of any first rejected promise }
最有用的是Promise 可以通过 Promise.all() 获取resolved 或rejected
如果所有的promise对象请求成功了,那么 allPromise 是由Promise 组成的数组。Promises的返回顺序与入数组栈的顺序有关。
但是如果最后一个promise reject了,allPromise 也将会进入 reject状态,不会等待其他的promises 被正确返回。
同时执行异步操作示例
为了演示Promise.all() 的工作流程,我们选择使用2个帮助类,resolveTimeout(value, delay) and rejectTimeout(reason, delay). `function resolveTimeout(value, delay) { return new Promise( resolve => setTimeout(() => resolve(value), delay) ); }
function rejectTimeout(reason, delay) { return new Promise( (r, reject) => setTimeout(() => reject(reason), delay) ); }`
resolveTimeout(value, delay) 返回一个Promise对象并携带一个参数值 另外,rejectTimeout,也将返回一个Promise对象,并携带拒绝的理由。
如模拟示例,在同一时间商店提供蔬菜和水果的列表,并且通过异步操作来访问每个列表: `const allPromise = Promise.all([ resolveTimeout(['potatoes', 'tomatoes'], 1000), resolveTimeout(['oranges', 'apples'], 1000) ]);
// wait... const lists = await allPromise;
// after 1 second console.log(lists); // [['potatoes', 'tomatoes'], ['oranges', 'apples']]`
const allPromise = Promise.all([...]) 返回新的allPromise的promise对象。 const lists = await allPromise 语句声明了等待1秒钟,直到所有的promise对象压入allpromise 数组中。 最后list中输出的结果为:[['potatoes', 'tomatoes'], ['oranges', 'apples']].
promises 数组的顺序直接影响结果的顺序。
蔬菜的promises是第一项,而水果的promises是输入数组中的第二项。结果数组包含相同顺序的值--第一个蔬菜列表和第二个水果列表。
3. 示例: 当一个Promise 发生阻塞时
现在想象一下这样的情况:杂货店里没有水果了。在这种情况下,让我们用一个错误提示返回水果的reject: new Error('Out of fruits!'): `const allPromise = Promise.all([ resolveTimeout(['potatoes', 'tomatoes'], 1000), rejectTimeout(new Error('Out of fruits!'), 1000) ]);
try { // wait... const lists = await allPromise; } catch (error) { // after 1 second console.log(error.message); // 'Out of fruits!' }`
在这种情况下,allPromise = Promise.all([...]),返回一个promise,然而, 当promise(fruits)返回一个错误new Error('Out of fruits!')所有的allpromise 对象也将返回reject 方法,并返回同样的错误。 即使蔬菜的promise已经实现了,Promise.all() 并不生效。Promise.all([...])的行为即 fail-fast. 如果队列中有一个 promise reject,其他的promise也是reject并且返回同样的理由。
4. 总结
Promise.all([...])是一个有用的辅助函数,它可以让你使用故障快速策略并行地执行异步操作,并将结果聚合到一个数组中。