forEach sum with arrow function在Firebase实时数据库中显示意外结果

时间:2017-10-19 08:37:14

标签: javascript node.js firebase firebase-realtime-database google-cloud-functions

从Firebase云功能我在Firebase Realtime DB中查询如下:

let logs = this.firebase.database()
.ref('logs')
.orderByChild("userId").equalTo(userId)
.once('value');

返回的数据:

{
  "id1abc": {
    "myValue": 1,
    "userId": "abc"
  },
  "id2abc": {
    "myValue": 2,
    "userId": "abc"
  },
  "id3abc": {
    "myValue": 3,
    "userId": "abc"
  }
}

查询返回一些条目,这些条目是我想要求和的值:

let loggedVal = 0;
logs.forEach(log => {
    loggedVal += log.val().myValue;
});
return loggedVal;

forEach中的箭头函数在这种情况下给出了正确的值(Sum等于6)。

但是当我删除这里的括号时:

let loggedVal = 0;
logs.forEach(log => loggedVal += log.val().myValue);
return loggedVal;

返回值不是总和,而只是来自我迭代的第一个元素的值(loggedVal == 6)。任何人都可以解释差异来自哪里?

3 个答案:

答案 0 :(得分:3)

根据firbase forEach文档,

  

您可以通过forEach回调随时取消枚举   函数返回true。

在第二种情况下,

logs.forEach(log => loggedVal += log.val().myValue);

您在第一次迭代中返回一些值(因为you are not using parenthesis),这被认为是真的。因此它会停止进一步的迭代,因此你不会得到总和而是第一个值。

答案 1 :(得分:1)

你误解了箭头功能格式。

第一个:

let loggedVal = 0;
logs.forEach(log => {
  loggedVal += log.val().myValue;
 });
 return loggedVal;

它等于ES5:

let loggedVal = 0;
logs.forEach(function(log){
  loggedVal += log.val().myValue;
 });

 return loggedVal;

但是第二个:

 let loggedVal = 0;
 logs.forEach(log => loggedVal += log.val().myValue);
 return loggedVal;

它与ES5相同:

 let loggedVal = 0;
 logs.forEach(function(log){
    return loggedVal += log.val().myValue);
 }); 
 return loggedVal;

箭头功能=> abc()表示{ return abc()},但=> { abc }表示{abc(); return;}

作为firebase的文件:

  

您可以通过让forEach回调函数返回true来随时取消枚举。

在第一项:return loggedVal += log.val().myValue); // === true,以便它停止递归.forEach

p.s:有人误解=> { abc }等于{ return { abc :abc} }

答案 2 :(得分:0)

这就是它应该是什么样子

const logs = {
  id1abc: {
    myValue: 1,
    userId: 'abc',
  },
  id2abc: {
    myValue: 2,
    userId: 'abc',
  },
  id3abc: {
    myValue: 3,
    userId: 'abc',
  },
};

Object.keys(logs).reduce((tmp, x) => tmp + logs[x].myValue, 0);