# Shallow to shallow implementation of an asynchronous summation function

## Simplification: sum of two numbers

Let's simply implement an asynchronous sum of two function

```function sumT(a, b) {
return await new Promise((resolve, reject) => {
asyncAdd(a, b, (err, res) => {
if(!err) {
resolve(res)
}
reject(err)
})
})
}

// test
const test = await sumT(1, 2)
console.log(test)
// 3```

## Deepening: sum of the majority

Above, we realize the sum of two numbers, and then extend it to the sum of the majority?

When it comes to array summation, we first think of reduce

The reduce() method executes a reducer function (executed in ascending order) provided by you for each element in the array, and summarizes its results into a single return value.

- MDN

`arr.reduce(callback(acc, cur[, idx[, arr]])[, initialValue])`

The callback function receives four parameters:

• acc: accumulator
• cur: current value
• idx: current index
• arr: source array

initialValue is optional,

• If initialValue: acc is initialValue, cur takes the first value in the array
• If not: acc takes the first value in the array and cur takes the second value in the array
```const arr = [1, 2, 3, 4];
const reducer = (acc, cur) => acc + cur;

// 1 + 2 + 3 + 4
console.log(arr.reduce(reducer));
// Output: 10

// 5 + 1 + 2 + 3 + 4
console.log(arr.reduce(reducer, 5));
// Output: 15```

Set the initial value to promise Resolve (0), 5 times of summation:

```function sum(...args) {
return new Promise(resolve => {
args.reduce((acc, cur) => acc.then(total => sumT(total, cur)), Promise.resolve(0)).then(resolve)
})
}

// test
await sum(1, 2, 3, 4, 5)
// 15```

However, it takes a long time. We can calculate the following time:

```console.time("sum")
// test
await sum(1, 2, 3, 4, 5)
// 15
console.timeEnd("sum")```

In other words, we spend 1s every time we sum, serial asynchronous sum, which is obviously not optimal

## Optimization: using promise all

We can work in pairs and use promise All sum, then set the sum in pairs and continue to sum, Know that only one remaining is the final result

```async function sum(...args) {
// Used to examine the process of each iteration
console.log(args)

// If there is only one, return directly
if(args.length === 1) return args[0]
let result = []
// In pairs, if there is one left, enter directly
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 intra group summation
return sum(...await Promise.all(result))
}

// test
test = await sum(1, 2, 3, 4, 5)
// 15```

```console.time("sum")
await sum(1, 2, 3, 4, 5)
console.timeEnd("sum")```