为什么 Firebase 在 once() 函数之外会丢失引用?

2023-12-28

我使用 Firebase 和 angularJS 来获取用户列表。我可以使用以下命令从数据库中读取所有用户once()功能,但我不明白为什么userList下面返回未定义

.service('userService', [function() {
    this.getUsers = function() {
        var users;
        var userList;
        var ref = firebase.database().ref('/users/');
        ref.once('value').then(function(snapshot) {
            users = snapshot.val();
            for(var key in users) {
                users[key].id = key;
                // do some other stuff
            }
            console.log(users); // outputs all users
        }).then(function(){
            userList = users; 
            console.log(userList); // outputs all users
        },(function(error){
            alert('error:  ' + error);
        });
        console.log(userList); // outputs 'undefined'
    }
}]);

我等待分配我的userList变量,直到我完成处理users,但没有运气。

这里有一些重要的东西我在涉及承诺/回调的地方丢失了,并且我在文档中找不到它;有人可以帮助我理解我的问题吗?


问题是(正如 imjared 所说)数据是从 Firebase 异步读取的。所以代码不会按照你想象的顺序执行。通过仅使用一些日志语句来简化它,最容易看出这一点:

.service('userService', [function() {
    this.getUsers = function() {
        var ref = firebase.database().ref('/users/');
        console.log("before attaching listener");
        ref.once('value').then(function(snapshot) {
            console.log("got value");
        });
        console.log("after attaching listener");
    }
}]);

其输出将是:

在附加监听器之前

附加监听器后

得到了价值

了解其执行顺序应该可以完美解释为什么在附加侦听器后无法打印用户列表。如果没有,我建议您也阅读这个很棒的答案:如何从异步调用返回响应 https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call

现在给出解决方案:您将either需要在回调中使用用户列表or返回一个承诺。

在回调中使用用户列表

这是处理异步代码的最古老的方法:将所有需要用户列表的代码移至回调中。

    ref.once('value', function(snapshot) {
        users = snapshot.val();
        for(var key in users) {
            users[key].id = key;
        }
        console.log(users); // outputs all users
    })

您正在将代码从“首先加载用户列表,然后打印其内容”重新构造为“每当加载用户列表时,打印其内容”。定义上的差异很小,但突然间您就完全有能力处理异步加载了。

您也可以对 Promise 执行相同的操作,就像在代码中所做的那样:

   ref.once('value').then(function(snapshot) {
        users = snapshot.val();
        for(var key in users) {
            users[key].id = key;
            // do some other stuff
        }
        console.log(users); // outputs all users
    });

但使用 Promise 比直接使用回调有一个巨大的优势:you can return一个承诺.

返回一个承诺

通常您不想将需要用户的所有代码放入getUsers()功能。在这种情况下你可以either将回调传递给getUsers()(我不会在这里展示,但它与您可以传递给的回调非常相似once()) or你可以返回一个承诺getUsers():

this.getUsers = function() {
    var ref = firebase.database().ref('/users/');
    return ref.once('value').then(function(snapshot) {
        users = snapshot.val();
        for(var key in users) {
            users[key].id = key;
            // do some other stuff
        }
        return(users);
    }).catch(function(error){
        alert('error:  ' + error);
    });
}

有了这项服务,我们现在可以调用getUsers()并在用户加载后使用生成的承诺来吸引用户:

userService.getUsers().then(function(userList) {
    console.log(userList);
})

这样你就驯服了异步野兽。嗯……至少现在是这样。即使经验丰富的 JavaScript 开发人员偶尔也会感到困惑,所以如果需要一些时间来适应,请不要担心。

使用异步和等待

现在该函数返回一个承诺,您可以使用async/await让上面的最终调用看起来更熟悉一些:

function getAndLogUsers() async {
    const userList = await userService.getUsers();
    console.log(userList);
}

您可以看到这段代码看起来几乎像同步调用,这要归功于使用await关键词。但为了能够使用它,我们必须标记getAndLogUsers(或者我们使用的任何父范围await) as async, 意思就是it返回一个Future也。所以有人打电话getAndLogUsers仍然需要了解其异步性质。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Firebase 在 once() 函数之外会丢失引用? 的相关文章

  • 链接 getElementById

    我一直在寻找这个问题的答案 但找不到答案 所以我想尝试一下 StackOverflow 在 javascript 中 这是否有效 x document getElementById myId y x getElementById mySec
  • 查找数组中多个最大值的索引

    我有一个示例数组 var arr 10 67 100 100 我想找到数组中最大值的索引 该函数仅查找一个索引 function max arr var max arr 0 var maxIndex 0 for var i 1 i lt a
  • 在函数调用时加载外部 Javascript

    我想知道如何从函数将外部 Javascript 加载到我的文档中 这是一种方法 function loadDaFun var script document createElement script script src path to y
  • 使用 Google Apps 脚本从 Firebase 读取数据

    因此 正如标题所示 我目前正在解决一个相当麻烦的问题 这是场景 我有一个 Google 电子表格 其中包含一个包含姓名 电子邮件和到期日期的模板 但是 它不包含实际数据 数据本身位于 Firebase 中并且不断变化 那么 我的目标是让sc
  • 获取语​​音通道的用户数

    我正在重写我的音乐部分朋友不和谐机器人 https top gg bot 629799045954797609 我试图弄清楚如何获取执行命令的人的语音通道中的用户数量 我到处都找过 但似乎找不到它或它的用法 现在我正在使用以下内容 modu
  • 如何从 Firebase 删除 Analytics 事件

    如何从 Firebase 中删除 Analytics 事件 在测试时 我在 Firebase Analytics 中编写了一些事件 Firebase 默认情况下按字母顺序对所有事件进行排序 因此 这些测试事件会与原始事件打断 我可以按计数来
  • 在生产中使用 css / javascript 源映射对性能有何影响?

    生产环境中应该使用源映射吗 除了调试之外 它们还有什么好处吗 由于额外的服务器往返 它们是否会影响应用程序加载时间 浏览器是否足够智能来加载 map应用程序加载和渲染后的资产 如果浏览器找不到 map asset 404错误 会对性能产生影
  • 在选择下拉列表中选择特定选项时添加输入框

    我需要在选择选项时将输入添加到选择选项中 每当用户选择 其他 时 就会出现一个输入框供用户输入数据 HTML
  • 添加数组的总和。显示1个输出

    更新 这个问题的答案如下 感谢在不同线程上进行的 dougtesting 将数组相加 显示总和 https stackoverflow com questions 45724641 add array together display su
  • 如何在 jQgrid 中隐藏列但在添加/编辑面板中显示此列

    我想要一种我使用的控制形式 但字段数量太高了 如何显示网格 但只有表单添加 编辑弹出面板中的某些字段显示所有字段 以下是您可以执行此操作的方法 colModel name email label E mail editable true h
  • 如何检查字符串中是否存在阿拉伯字符(javascript)

    如何用javascript语言检查字符串中是否存在阿拉伯字符 根据维基百科 http en wikipedia org wiki Basic Multilingual Plane 阿拉伯字符属于 Unicode 范围 0600 06FF 因
  • 需要将焦点放在react中的div上

    我有一个之前用 H1 标签包裹的文本 页面加载后 我需要专注于该文本 为了方便起见 我将它包装在 div 中 render const translate billing primaryContactSelection true this
  • javascript 中的自动转换:像 stringvar = 1+stringvar 这样完成时,不是应该将字符串转换为数字吗?

    火狐32 Win 7 使用暂存器时 var a 2 a 1 1 a console log a typeof a a 1 a 1 console log a typeof a 在控制台中导致 02 string 101 number 难道我
  • 使用 System.js 导入 Typescript 编译的模块时出错

    我最近正在学习使用 system js 导入由 Typescript 编译的模块 这些模块之前是为 require js 编译的 并且工作正常 但是合并到system js时 应用时无法导入模块系统生产 js 控制台说 Uncaught i
  • Twitter 引导选项卡和 JavaScript 事件

    我正在一个项目中使用 twitter bootstrap 特别是它的选项卡功能 http twitter github com bootstrap javascript html tabs http twitter github com b
  • 如何创建浏览器插件?

    我必须创建一个插件 当用户将鼠标悬停在某些术语上时 该插件必须显示信息 谁能告诉我如何做的方向 我对创建插件没有太多想法 我知道我想要做的事情可以通过java脚本来完成 但是java脚本文件可以作为浏览器插件安装吗 任何对此的想法将不胜感激
  • 如何使用 jquery 生成并附加随机字符串

    一般性 我想使用 jQuery 或 javascript 将随机字符串附加到元素的属性 规格 我需要引用 CDN 上的 CSS 文件 不幸的是 每次更新该 CSS 文件时 CDN 都会更改该文件的 URL 所以我不能简单地引用静态 URL
  • 如何从 vue 组件调用 App.vue 中的方法

    我有一个 vue 组件和一个 vue 元素声明 如下所示 Vue component todo item template li This is a todo li methods test function I am getting an
  • JavaScript:如何在 Internet Explorer 中模拟更改事件(委托)

    UPDATE 回顾 小提琴和赏金 这个问题并没有引起太多关注 所以我将花一些时间来解决这个问题 我知道我的答案和问题都过于冗长 这就是为什么我继续设置这把小提琴 http jsfiddle net vVA8N 在我看来 这是我目前必须用来接
  • 使用 Javascript 删除字符串的最后一个字符

    我有一个DIV与一些字符 如何在每次单击时删除文本中的最后一个字符DIV itself 删除第一个字符 div on click function this text function index text return text repl

随机推荐

  • 如何减少RadioButton绑定代码?

    我正在跟进这个答案关于如何将枚举 在我的例子中是整数 数据绑定到RadioButtons https stackoverflow com a 2908885 171121 但是如果我有几个 TabItems 每个 TabItems 都有 1
  • 如何在代码后面设置DataGrid行的背景颜色?

    我创建一个DataGrid我的代码后面的对象并设置内容obj ItemsSource 现在我想在后面的代码中设置特定行的背景颜色 我怎样才能实现这个目标 Update 我创建了DataGrid后面代码中的对象如下 var dataGrid
  • Java 归并排序

    我正在尝试创建一个合并排序方法 但它不断给出错误的排序 我在哪里可以更改以使其真正对数组进行排序 代码的哪一部分必须不同 感谢您的时间 public static void mergeSort int array int left int
  • 使用 django 测试客户端发送 JSON

    我正在开发一个 django 项目 它将作为 webhook 的端点 Webhook 会将一些 JSON 数据发布到我的端点 然后端点将解析该数据 我正在尝试为其编写单元测试 但我不确定是否正确发送了 JSON 我在管道端点中不断收到 Ty
  • Netbeans 和 C++ 安装

    我在使用 Netbeans 7 4 和 Cygwin 4 x 编译 C 程序时遇到了一个小问题 我已经完成了 netbeans 教程中的所有操作 我已经安装了 gcc gdb g 和 make 编译器 Netbeans 属性中的每条路径都已
  • Java FTP 的服务器端实现

    我想建立一个后台没有实际文件的FTP服务器 相反 我希望上传到它的文件立即由我的后端处理 上传目录的文件列表应包含尚未处理的文件 删除或移动应该是不可能的 另外 在下载方面 我想展示我能够提供的那些文件 但文件应根据需要再次由后端创建 由于
  • 为什么 JSP 不支持表单上的“put”方法?有没有办法在jsp表单上使用put方法? [复制]

    这个问题在这里已经有答案了 我正在尝试实施putJSP形式的方法 但似乎是支持的 背后的原因是什么 如果我使用 HTML 而不是 JSP 并调用实现的 servlet 来接受 put 请求 那么它会按预期工作 但相同的代码不能在 JSP 上
  • Flask-Security user_registered 信号在 Python 3.3 中未收到,但在 2.7 中有效

    我正在尝试使用 user registered 信号 以便在用户使用 Flask security 注册时为用户设置默认角色 如下链接所示 在 Flask 安全性中设置默认角色 https stackoverflow com questio
  • 比较浮点数组时 rspec 测试的舍入问题

    我想检查一种方法的结果 result should 1 0 2 0 3 0 但我收到一个错误 expected 1 0 2 0 3 0 got 1 0 2 0 3 0 using 我认为问题在于四舍五入 但我不知道如何比较它们 例如偏差为0
  • python os.system 问题:“sh:1:找不到[命令]”;命令交互工作

    我正在尝试从 Python 运行系统调用 我的 Python 脚本中有一行这样读 return os system crux tide index crux是我的程序中存在的一个程序 home 目录 如果我输入命令crux tide ind
  • WPF、Project White 和 Infragistics

    我正在尝试使用白色计划 http white codeplex com 为我的 WPF 应用程序编写自动化测试 一切都很顺利 直到我尝试与 Infragistics 控件进行交互 有人有过这种设置的经验吗 您能否发布一个示例 说明我如何 例
  • 将 Spring、Hibernate、JPA 和 Tomcat 与多个数据库结合使用的选项

    我有一个 java web 应用程序在 Spring 2 5 6 Hibernate 3 4 以 Hibernate 作为 JPA 提供程序 和 Tomcat 6 下运行 我让它使用一个数据库模式 持久性单元 但现在需要连接到 2 个模式
  • 将div对齐到右侧[重复]

    这个问题在这里已经有答案了 您好 我有以下 HTML 在容器内有标题 部分和 div 在我当前的 CSS 下面 带有类 rightSideDiv 的 div 不会显示在部分元素的右侧 container height 500px widht
  • 变量函数名Javascript

    我正在对数组进行排序 myArray sort comparators some comparator 我有几个比较器可供选择 comparators asc firstname comparator function o1 o2 desc
  • Angular 2 RC4 路由器在激活前获取预期路由

    我试图在激活之前确定路由是什么 以便我可以缓存它并在用户登录后将用户重定向回该路由 在旧的测试版路由器中我可以调用ComponentInstruction routeName在激活钩子中 但在较新的钩子中canActivate 警卫 我没有
  • 在 Jqgrid 中如何显示用户通过内联编辑在数据库中更新的下拉值

    下面是代码 其中用户选择的下拉列表正在数据库中更新 但是刷新页面后我想显示用户之前选择的数据库中的值 现在刷新页面后单元格为空白 请帮忙 qr SELECT id emp id emp name att date emp join date
  • Ursina 模块中的 invoke() 做了什么

    我导入了Ursina module https www ursinaengine org 它是一个游戏引擎 我查找了教程并在代码中invoke 被使用了 我尝试查找文档 但似乎没有相关信息 本教程中的代码如下 from ursina imp
  • 任何可见 unicode 字母字符的 JavaScript 正则表达式模式

    我正在开发一个 JavaScript 应用程序 它要求我识别 任何可见的 Unicode 字母字符 数字 0 9 空格 下划线和句点 的集合 建议的正则表达式模式是 0 9 p L 但这似乎在 JavaScript 中不起作用 给我带来麻烦
  • cjk共享的相同汉字是否共享相同的unicode值?

    中国与日本 韩国共有近808个汉字 如門 英文是门的意思 中文的unicode值門是9580 日韩呢門 日语和韩语的unicode值是多少門 它们相同吗 我不是特别熟悉 Unicode 如何处理汉字 但看起来该字符是共享的 U 9580 h
  • 为什么 Firebase 在 once() 函数之外会丢失引用?

    我使用 Firebase 和 angularJS 来获取用户列表 我可以使用以下命令从数据库中读取所有用户once 功能 但我不明白为什么userList下面返回未定义 service userService function this g