一道字节笔试题,实现一个异步求和函数
2023-03-14 09:41:52 时间
题目:
提供一个异步 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 + 4
- console.log(arr.reduce(reducer));
- // 输出: 10
- // 5 + 1 + 2 + 3 + 4
- console.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)
- // 15
- console.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)
- // 15
- console.time("sum")
- await sum(1, 2, 3, 4, 5)
- console.timeEnd("sum")
来自:https://github.com/Advanced-Frontend/Daily-Interview-Question
相关文章
- 数据孤岛是业务效率的无声杀手
- 2023展望:新的一年将给大数据分析领域带来什么?
- 阿里云ADB基于Hudi构建Lakehouse的实践
- 大数据在医疗保健领域的使用案例
- 微软增加说明:KB5021751 更新扫描已经 / 即将过时 Office 过程中不会触碰用户隐私
- 2022 Gartner全球云数据库管理系统魔力象限发布 腾讯云数据库入选
- 场景化、重实操,分享一个实时数仓实践案例
- Arctic的湖仓一体践行之路
- 分布式计算MapReduce究竟是怎么一回事?
- 淘系数据模型治理优秀实践
- 大数据分析对医疗保健的影响
- 当我们说大数据Hadoop,究竟在说什么?
- 2022年及以后大数据的五个发展趋势
- 网易严选离线数仓治理实践
- 2023 年数据治理趋势
- 一份“靠谱”的年度经营计划,你学会了吗?
- 漫谈对大数据的思考
- 测试一下,读懂数据的能力,你有吗?
- 用艺术的眼光探索数据之美
- 聊聊数据分析成果如何落地