简体   繁体   English

从回调函数返回值

[英]Returning a value from callback function

I am using the on() method to retrieve a data snapshot in our database, but I need to be able to store this snapshot value so that I can use it to retrieve another separate snapshot. 我正在使用on()方法来检索数据库中的数据快照,但是我需要能够存储此快照值,以便可以使用它来检索另一个单独的快照。

Here is what our database looks like: Firebase Real-Time Database 我们的数据库如下所示: Firebase实时数据库

There is a node for users and a separate node for devices. 有一个用于用户的节点,一个用于设备的单独节点。 Each user has a child "devices" which is a list of devices associated with that user. 每个用户都有一个子“设备”,它是与该用户关联的设备列表。 The user that I have expanded only has one device. 我扩展的用户只有一个设备。

What I am trying to do is store this deviceID, and then do a separate query to find that device in the "Devices" node. 我想做的是存储此deviceID,然后执行单独的查询以在“设备”节点中找到该设备。 Here is what my code looks like: 这是我的代码:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData);

And then the callback function looks like this: 然后,回调函数如下所示:

function getData(data)
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
}

which is just grabbing the first device in the users device list and printing it to the console. 这只是获取用户设备列表中的第一台设备并将其打印到控制台。 I am trying to figure out how to return this value so that I can use it when getting the data from the Devices tree. 我试图弄清楚如何返回此值,以便在从“设备”树中获取数据时可以使用它。 Which, I'm guessing, would look something like this: 我猜这看起来像这样:

let deviceRef = database.ref("devices/").child(retrievedValue);
deviceRef.on("value", getData2);

Where retrievedValue is the deviceID that I got from the first query. 其中recoveredValue是我从第一个查询获得的deviceID。

Is it possible to do this in javascript, or is there a better way? 有可能在javascript中执行此操作,还是有更好的方法? I know similar questions have already been asked, but I've found all the examples I've seen online to be really confusing and not very helpful for me. 我知道已经问过类似的问题,但是我发现我在网上看到的所有示例确实令人困惑,对我没有太大帮助。 Any help at all would be super appreciated because I am kind of stuck on this. 任何帮助都将不胜感激,因为我对此有些执着。 Thanks! 谢谢!

In order to achieve that, you have to modify your callback as following: 为了实现这一点,您必须修改回调,如下所示:

function getData(data, callback)
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  callback(currentDevice)
}

Then we you call your callback from within the code, do it like this: 然后,我们从代码内调用回调,如下所示:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData((this_is_the_value_from_inside_callback) => {
  console.log(`your value: ${this_is_the_value_from_inside_callback}`)
});

You can also try to run this little snippet (I used PlayCode), to see it more friendly testing environment 您也可以尝试运行此小片段(我使用了PlayCode),以查看更友好的测试环境

somefunction = (data, callback) => {

  console.log(`data: ${data}`)
  data += 100
  console.log(`data: ${data}`)
  callback(data)
}

somefunction(100, (dataReturned) => {
  console.log(`data returned: ${dataReturned}`)
})

You have to learn about promises and asynchronous programming. 您必须了解Promise和异步编程。 Here are two ways to do what you want: 这是两种您可以做的事情:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.once("value").then((data) {
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  let deviceRef = database.ref("devices/").child(currentDevice);
  return deviceRef.once("value");
}).then((value) {
  console.log("value is " + value);
})

or with async/await: 或使用async / await:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
let data = await ref.once("value")
currentDevice = Object.keys(data.val())[0];
console.log("current device: " + currentDevice); 
let deviceRef = database.ref("devices/").child(currentDevice);
let value = await deviceRef.once("value");
console.log("value is " + value);

I'm more confident about the second one as I'm typing these without testing. 我对第二个更加有信心,因为我无需测试即可输入这些内容。

These links would be helpful to start learning this stuff: https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html https://firebase.google.com/docs/functions/terminate-functions 这些链接将有助于您开始学习以下内容: https : //firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html https://firebase.google.com/docs/functions/终止功能

Edit: I fixed the code above by replacing on with once . 编辑:我固定上面的代码通过更换ononce However now this is not listening to changes in the db anymore. 但是现在,它不再监听数据库中的更改。 To correct your code to listen to user's device changes: 要更正代码以侦听用户的设备更改,请执行以下操作:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData);

function getData(data) // may need to place this before the code above
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  let deviceRef = database.ref("devices/").child(currentDevice);

  // no need to listen to this, as a change in one device would fire 
  // for every user. you probably don't want that. 
  deviceRef.once("value", (data) { 
    console.log(data);
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM