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
26
27
async function asyncAdd(a, b) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(a + b);
}, 500);
});
}

function asyncReduce(fn) {
return async function (arr) {
return arr.reduce((old, newOne) => {
// 简化
return Promise.resolve(old).then((data) => {
return fn.call(this, data, newOne);
});
// return new Promise((resolve) => {
// Promise.resolve(old).then(data => {
// resolve(fn(data, newOne));
// });
// });
});
};
}

asyncReduce(asyncAdd)([1, 2, 3]).then(data => {
console.log(data);
});
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
26
27
28
29
30
function reduce(arr, cb, initial = null) {
function iterator(res, leftArr) {
if (leftArr.length == 1) {
return cb(res, leftArr[0]);
}

return cb(res, leftArr[0]).then(
result => iterator(result, leftArr.slice(1))
);
}

if (initial) {
return iterator(initial, arr);
}
else {
return iterator(arr[0], arr.slice(1));
}
}

// 测试用例
function cb(res, i) {
return new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(res + i);
}, 1000);
});
}

reduce([1, 2, 3, 4, 5], cb);
reduce([1, 2, 3, 4, 5], cb, 10);