说在前面
🎈promise.all()大家都用过吗?今天来仿写一个promise.all
题目描述
给定一个异步函数数组 functions
,返回一个新的 promise 对象 promise
。数组中的每个函数都不接受参数并返回一个 promise。所有的 promise 都应该并行执行。
promise
resolve 条件:
- 当所有从
functions
返回的 promise 都成功的并行解析时。promise
的解析值应该是一个按照它们在functions
中的顺序排列的 promise 的解析值数组。promise
应该在数组中的所有异步函数并行执行完成时解析。
promise
reject 条件:
- 当任何从
functions
返回的 promise 被拒绝时。promise
也会被拒绝,并返回第一个拒绝的原因。
请在不使用内置的 Promise.all
函数的情况下解决。
示例 1:
输入: functions = [ () => new Promise(resolve => setTimeout(() => resolve(5), 200)) ] 输出: {"t": 200, "resolved": [5]} 解释: promiseAll(functions).then(console.log); // [5] 单个函数在 200 毫秒后以值 5 成功解析。
示例 2:
输入: functions = [ () => new Promise(resolve => setTimeout(() => resolve(1), 200)), () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100)) ] 输出: {"t": 100, "rejected": "Error"} 解释: 由于其中一个 promise 被拒绝,返回的 promise 也在同一时间被拒绝并返回相同的错误。
示例 3:
输入: functions = [ () => new Promise(resolve => setTimeout(() => resolve(4), 50)), () => new Promise(resolve => setTimeout(() => resolve(10), 150)), () => new Promise(resolve => setTimeout(() => resolve(16), 100)) ] 输出: {"t": 150, "resolved": [4, 10, 16]} 解释: 所有的 promise 都成功执行。当最后一个 promise 被解析时,返回的 promise 也被解析了。
提示:
- 函数
functions
是一个返回 promise 的函数数组 1 <= functions.length <= 10
解题思路
首先创建一个新的 Promise 对象,用于处理异步操作的结果。然后,函数创建了一个与传入的函数数量相同长度的空数组 res,用于存储每个函数执行的结果。同时,定义了一个计数器 cnt,用于记录已经执行完成的函数数量。
接下来,函数使用 forEach 方法对传入的函数数组进行迭代。在每次迭代中,函数调用当前函数 fn,并通过 .then() 方法注册一个回调函数来处理异步操作的结果。当异步操作成功完成时,回调函数会将结果存储在 res 数组的相应位置,并将计数器 cnt 增加 1。如果计数器 cnt 的值等于 res 数组的长度,表示所有函数都已经执行完成,则通过 resolve 方法将结果数组 res 作为 Promise 的最终结果返回。
如果在任何一个函数执行过程中出现错误,则通过 catch 方法将错误信息传递给 Promise 的 reject 方法,使 Promise 进入拒绝状态,并传递错误信息。
最后,通过调用 promiseAll 函数并传入一个包含一个异步操作的函数的数组,可以得到一个 Promise 对象,当异步操作成功完成时,该 Promise 对象会将结果数组 [42] 返回,并通过 .then() 方法中的回调函数进行处理。
AC代码
/** * @param {Array<Function>} functions * @return {Promise<any>} */ var promiseAll = function (functions) { return new Promise((resolve, reject) => { const res = new Array(functions.length); let cnt = 0; functions.forEach((fn, fnInd) => { fn() .then((response) => { res[fnInd] = response; cnt++; if (cnt === res.length) resolve(res); }) .catch((err) => { reject(err); }); }); }); }; /** * const promise = promiseAll([() => new Promise(res => res(42))]) * promise.then(console.log); // [42] */ const promise = promiseAll([() => new Promise((res) => res(42))]); promise.then(console.log); // [42]
公众号
关注公众号『前端也能这么有趣
』,获取更多有趣内容。
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。