forEach 和箭头函数在 Firebase 实时数据库中给出了意想不到的结果

Posted

技术标签:

【中文标题】forEach 和箭头函数在 Firebase 实时数据库中给出了意想不到的结果【英文标题】:forEach sum with arrow function gives unexpected results in Firebase Realtime Database 【发布时间】:2017-10-19 08:37:14 【问题描述】:

从 Firebase Cloud Functions 我在 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 中的箭头函数在这种情况下给了我正确的值(总和等于 6)。

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

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

返回值不是总和,而只是我正在迭代的第一个元素的值(loggedVal == 6)。谁能解释差异来自哪里?

【问题讨论】:

首先如何在Object 中使用forEach?您向我们显示的返回数据不是符合Array.forEach 条件的Array 【参考方案1】:

根据 firbase forEach 文档,

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

这里是你的第二种情况,

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

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

【讨论】:

我知道这将是 javascript 基础知识!只是找不到合适的问题要问。谢谢!【参考方案2】:

你对箭头函数格式有误解。

第一个:

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

【讨论】:

【参考方案3】:

这就是它的样子

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);

【讨论】:

以上是关于forEach 和箭头函数在 Firebase 实时数据库中给出了意想不到的结果的主要内容,如果未能解决你的问题,请参考以下文章

Array.from和forEach中的“箭头函数”在IE 11中不起作用,它在console.how中抛出语法错误来解决?

箭头函数

ES6箭头函数

异步箭头函数预期没有返回值

箭头函数

Flutter:未为 DataSnapshot 类定义 forEach 方法