本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
点击上方 三分钟学前端,关注公众号
回复交流,加入前端编程面试算法每日一题群
面试官也在看的前端面试资料
题目:
提供一个异步 add 方法如下,需要实现一个 await sum(...args) 函数:
function asyncAdd(a, b, callback) { setTimeout(function () { callback(null, a + b); }, 1000);}简化:两数之和
我们先来简单的实现一个异步两数之和函数
function sumT(a, b) { return await new Promise((resolve, reject) => { asyncAdd(a, b, (err, res) => { if(!err) { resolve(res) } reject(err) }) })}// 测试const test = await sumT(1, 2)console.log(test)// 3加深:多数之和
上面我们实现了两数之和,然后扩展到多数之和喃?
提到数组求和问题,我们首先想到的是 reduce
reduce()方法对数组中的每个元素执行一个由您提供的 reducer 函数 (升序执行),将其结果汇总为单个返回值。—— MDN
arr.reduce(callback(acc, cur[, idx[, arr]])[, initialValue])callback 函数接收 4 个参数:
acc:累计器cur:当前值idx:当前索引arr:源数组
其中, initialValue 可选,
如果有
initialValue:acc取值为initialValue,cur取数组中的第一个值如果没有:
acc取数组中的第一个值,cur取数组中的第二个值
const arr = [1, 2, 3, 4];const reducer = (acc, cur) => acc + cur;// 1 + 2 + 3 + 4console.log(arr.reduce(reducer));// 输出: 10// 5 + 1 + 2 + 3 + 4console.log(arr.reduce(reducer, 5));// 输出: 15关于本题:来自 @champkeh
设置初始值为 Promise.resolve(0) ,经历 5 次求和:
function sum(...args) { return new Promise(resolve => { args.reduce((acc, cur) => acc.then(total => sumT(total, cur)), Promise.resolve(0)).then(resolve) })}// 测试await sum(1, 2, 3, 4, 5)// 15但这存在一个耗时较长的问题,我们可以计算下时间:
console.time("sum")// 测试await sum(1, 2, 3, 4, 5)// 15console.timeEnd("sum")也就是说,我们每次求和都会花费 1s,串行异步求和,这显然不是最优的
优化:使用 Promise.all
我们可以两两一组,使用 Promise.all 求和,再把和两两一组继续求和…..,知道只剩余一个就是最终的结果
async function sum(...args) { // 用于考察每次迭代的过程 console.log(args) // 如果仅有一个,直接返回 if(args.length === 1) return args[0] let result = [] // 两两一组,如果有剩余一个,直接进入 for(let i = 0; i < args.length - 1; i+=2) { result.push(sumT(args[i], args[i + 1])) } if(args.length%2) result.push(args[args.length-1]) // Promise.all 组内求和 return sum(...await Promise.all(result))}// 测试test = await sum(1, 2, 3, 4, 5)// 15console.time("sum")await sum(1, 2, 3, 4, 5)console.timeEnd("sum")来自:https://github.com/Advanced-Frontend/Daily-Interview-Question
最后
欢迎关注「三分钟学前端」,回复「交流」自动加入前端三分钟进阶群,每日一道编程算法面试题(含解答),助力你成为更优秀的前端开发!
》》面试官也在看的前端面试资料《《
“在看和转发” 就是最大的支持