-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
不使用加号 + 实现异步相加函数
题目描述
给定一个辅助函数如下:
function asyncAdd(a, b, callback) {
setTimeout(function() {
callback(a + b)
}, 1000)
}在不使用加号 + 的情况下,实现一个函数,实现两个异步相加,返回一个异步结果。示例如下:
sum(1,2,3,4,5,6,7,8,9,10,11).then(sum => console.log(sum))思路
先说下整体思路,不能使用加号的话,那就只能借助辅助函数来完成运算。因为最终返回的是 Promise,所以一开始想到的就是需要对辅助函数进行包装,使得从语言层面能异步控制它。接下来就是对参数个数进行分析,理想状态下就是对参数不停地进行二分操作,降低时间复杂度,将其变为 O(log n) 就是最佳时间。在二分地过程中,涉及到递归,递归终止条件就是只有一个参数,这时候就可以直接返回。如果是还剩 2 个参数,调用包装过的辅助函数,返回一个 Promise,然后通过 then 链式调用,将结果返回。
代码实现
function asyncAdd(a = 0, b = 0, callback) {
setTimeout(function() {
callback(a + b)
}, 1000)
}
const add = (a = 0, b = 0) => new Promise((resolve) => asyncAdd(a, b, resolve));
function sum(...args) {
if (args.length === 1) return new Promise((resolve) => resolve(args));
if (args.length === 2) {
return new Promise((resolve) => asyncAdd(args[0], args[1], resolve));
}
let params = [];
for (let i = 0; i < args.length; i += 2) {
if (i + 1 < args.length) {
params.push([args[i], args[i + 1]]);
} else {
params.push([args[i]]);
}
}
let fns = []
params.forEach(([a, b]) => {
fns.push(add(a, b));
});
return Promise.allSettled(fns).then((res) => {
const answers = res.map(item => item.value);
console.log(answers)
return sum(...answers);
})
}测试
const start = Date.now();
sum(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25).then(sum => {
const end = Date.now()
console.log('sum =', sum)
console.log(`time = ${(end - start) / 1000}s`)
})
// [
// 3, 7, 11, 15, 19, 23,
// 27, 31, 35, 39, 43, 47,
// 25
// ]
// [
// 10, 26, 42, 58,
// 74, 90, 25
// ]
// [ 36, 100, 164, 25 ]
// [ 136, 189 ]
// sum = 325
// time = 5.018s可以看到,在时间上并不是串行的 25 秒,而是 5 秒,极大地提升了运算速度。
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels