咱們先來簡單的實現一個異步兩數之和函數前端
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
複製代碼
上面咱們實現了兩數之和,而後擴展到多數之和喃?git
提到數組求和問題,咱們首先想到的是 reduce
github
reduce()
方法對數組中的每一個元素執行一個由您提供的reducer函數(升序執行),將其結果彙總爲單個返回值。面試—— MDN算法
arr.reduce(callback(acc, cur[, idx[, arr]])[, initialValue])
複製代碼
callback
函數接收4個參數:數組
acc
:累計器cur
:當前值idx
: 當前索引arr
:源數組其中, initialValue
可選,markdown
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
次求和:async
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
求和,再把和兩兩一組繼續求和…..,知道只剩餘一個就是最終的結果
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")
複製代碼