數組的reduce方法

數組的reduce方法

async await reduce array數組

你們對數組的map,filterforEach等的操做應該都比較熟悉了。這兩天寫代碼的時候用到了reduce方法,一不當心寫出了一個bug,在此記錄一下。異步

首先,reduce的用法以下:async

對數組中的全部元素調用指定的回調函數。該回調函數的返回值爲累積結果,而且此返回值在下一次調用該回調函數時做爲參數提供。函數

語法:翻譯

array.reduce(callback[,initialValue]) //注意這時候只能是同步方法
function callbackfn(previousValue, currentValue, currentIndex, array1)
參數 含義
previousValue 經過上一次調用回調函數得到的值。若是向 reduce 方法提供initialValue,則在首次調用函數時,previousValue 爲 initialValue。否者將是調用數組的第一項
currentValue 當前數組元素的值。
currentIndex 當前數組元素的數字索引。
array1 包含該元素的數組對象。

實現:code

// 實現數組的每一項之和
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方法對象
}

這樣咱們就清楚爲何上面會打印這麼奇怪的結果了。下面咱們只要作小小的修改,就能夠獲得正確的結果:get

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裏面執行異步方法~回調函數

相關文章
相關標籤/搜索