数组的reduce方法
async
await
reduce
array
大家对数组的map
,filter
,forEach
等的操作应该都比较熟悉了。这两天写代码的时候用到了reduce方法,一不小心写出了一个bug,在此记录一下。
首先,reduce的用法如下:
对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供。
语法:
array.reduce(callback[,initialValue]) //注意这时候只能是同步方法
function callbackfn(previousValue, currentValue, currentIndex, array1)
参数 | 含义 |
---|---|
previousValue | 通过上一次调用回调函数获得的值。如果向 reduce 方法提供initialValue,则在首次调用函数时,previousValue 为 initialValue。否者将是调用数组的第一项 |
currentValue | 当前数组元素的值。 |
currentIndex | 当前数组元素的数字索引。 |
array1 | 包含该元素的数组对象。 |
实现:
// 实现数组的每一项之和
var arr = [1,2,3,4]
arr.reduce((pre,cur) => {return pre + cur}) // return 10
实现数组的每一项转化为对象,例({1: 1, 2: 2, 3: 3, 4: 4})
var arr = [1,2,3,4]
arr.reduce((final,cur) => {
final[cur] = cur
return final
}, {}) // return {1: 1, 2: 2, 3: 3, 4: 4}
BUG
昨天的代码,我是这么实现的:
async function getGroup() {
...
}
async function getGroups() {
var arr = [1,2,3]
const result = arr.reduce(async (final,cur) => {
final[cur] = await getGroup(cur)
console.log(final, '<===final')
return final
}, {})
}
// final的打印值
{ '9ddc9834-9344-4cc1-be38-ba2d0e9d17c5': { recommendType: 1, weight: 123 } } '<===final'
Promise {
_c: [],
_a: undefined,
_s: 1,
_d: true,
_v: { '9ddc9834-9344-4cc1-be38-ba2d0e9d17c5': { recommendType: 1, weight: 123 } },
_h: 0,
_n: false,
'9bb6ed56-29a3-47e5-89a8-b652e8f08ef8': { recommendType: 2, weight: 12 } } '<===final'
Promise {
_c: [],
_a: undefined,
_s: 0,
_d: false,
_v: undefined,
_h: 0,
_n: false,
'30ddd8c9-2132-4d27-bc4b-4d27305acec9': {} }'<===final'
我们可以看到final的值并不是我们预期的,循环中只有第一个值是对的,后面的值都不对,而且看起来是个Promise对象。这是为什么呢?
接下来看到上面的实现翻译成reduce的底层实现方式:
var final = {}
async function getGroup(final, cur){
final[cur] = await getGroup(cur)
console.log(final, '<===final')
return final
}
for(var i = 0, i < arr.lenght, i++) {
final = getGroup(final, arr[i])
//这里没有用async await执行异步方法,导致,传回的final只是个Promise方法对象
}
这样我们就清楚为什么上面会打印这么奇怪的结果了。下面我们只要做小小的修改,就可以得到正确的结果:
var temp = {}
async function getGroup() {
...
}
async function getGroups() {
var arr = [1,2,3]
const result = arr.reduce(async (final,cur) => {
temp[cur] = await getGroup(cur)
console.log(temp, '<===final')
return temp
}, {})
}
以后还是尽量避免在reduce里面执行异步方法~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。