Javascript 使用firebase在给定键数组的情况下获取多个单独的值
我正在尝试访问Firebase中的多个单独密钥。我使用一个基于承诺的函数和一个Javascript 使用firebase在给定键数组的情况下获取多个单独的值,javascript,firebase,firebase-realtime-database,promise,Javascript,Firebase,Firebase Realtime Database,Promise,我正在尝试访问Firebase中的多个单独密钥。我使用一个基于承诺的函数和一个for循环来迭代给定的键 代码如下: function getFirebaseData(key_arr) { var ref_obj, data_obj = {}; return new Promise(function(resolve) { for(var i = 0; i < key_arr.length; i++) { ke
for
循环来迭代给定的键
代码如下:
function getFirebaseData(key_arr)
{
var ref_obj,
data_obj = {};
return new Promise(function(resolve)
{
for(var i = 0; i < key_arr.length; i++)
{
key_str = key_arr[i];
ref_obj = firebase.database().ref('path/'+key_str);
ref_obj.on('value', function(snapshot)
{
data_obj[key_str] = snapshot.val();
});
}
resolve(data_obj);
});
}
问题是,我得到的结果不是全部三个键;我只有一个。我想这是因为for
循环中的代码是异步的,所以resolve
只给我第一个键
我如何重写它,以便等待for
循环完成并返回完整结果。函数getFirebaseData(key\u arr)
function getFirebaseData(key_arr)
{
var ref_obj,
data_obj = {},
promises = [];
for(var i = 0; i < key_arr.length; i++)
{
key_str = key_arr[i];
promises.push(
new Promise(function(resolve)
{
ref_obj = firebase.database().ref('path/'+key_str);
ref_obj.on('value', function(snapshot)
{
data_obj[key_str] = snapshot.val();
});
resolve(data_obj);
})
)
}
return Promise.all(promises);
}
{
var ref_obj,
数据_obj={},
承诺=[];
对于(变量i=0;i
最小的代码更改可能是这样的。基本上,是为了立即兑现承诺。创建承诺数组并通过Promise.all
函数getFirebaseData(key\u arr)解析它
{
var ref_obj,
数据_obj={},
承诺=[];
对于(变量i=0;i
最小的代码更改可能是这样的。基本上,是为了立即兑现承诺。创建承诺数组并通过
Promise对其进行解析。所有
前面的答案都是可靠的,除了返回的承诺解析为数据对象数组
因此,您需要做的是将循环的每个迭代更改为一个承诺,然后使用promise.all
以下是您使用ES2015的方式-因为您使用的是承诺,所以ES2015无论如何都不是一个延伸
function getFirebaseData(key_arr) {
return Promise.all(key_arr.map(key_str =>
new Promise((resolve, reject) =>
firebase.database().ref('path/'+key_str).once('value', snapshot =>
resolve ([key_str, snapshot.val()])
)
)
)).then(results =>
results.reduce((result, [key, value]) => {
result[key] = value;
return result;
}, {})
);
}
通过以下方式传送到旧式ES5:
function getFirebaseData(key_arr) {
return Promise.all(key_arr.map(function (key_str) {
return new Promise(function (resolve, reject) {
return firebase.database().ref('path/' + key_str).once('value', function (snapshot) {
return resolve([key_str, snapshot.val()]);
});
});
})).then(function (results) {
return results.reduce(function (result, item) {
var key = item[0],
value = item[1];
result[key] = value;
return result;
}, {});
});
}
每个承诺现在都解析为一个数组,基本上[键,值]
.then after Promise.all将所有这些结果组合到一个对象中,如:{key1:value1,key2:value2,
上面的代码使用了。once('value')
而不是。on('value'
)-正如评论中指出的,使用。on
会让听者附加。因为承诺只能解决一次,所以使用。once
前面的答案是可靠的,除了返回的承诺解析为一个
数据数组\u obj
因此,您需要做的是将循环的每个迭代更改为一个承诺,然后使用promise.all
以下是您使用ES2015的方式-因为您使用的是承诺,所以ES2015无论如何都不是一个延伸
function getFirebaseData(key_arr) {
return Promise.all(key_arr.map(key_str =>
new Promise((resolve, reject) =>
firebase.database().ref('path/'+key_str).once('value', snapshot =>
resolve ([key_str, snapshot.val()])
)
)
)).then(results =>
results.reduce((result, [key, value]) => {
result[key] = value;
return result;
}, {})
);
}
通过以下方式传送到旧式ES5:
function getFirebaseData(key_arr) {
return Promise.all(key_arr.map(function (key_str) {
return new Promise(function (resolve, reject) {
return firebase.database().ref('path/' + key_str).once('value', function (snapshot) {
return resolve([key_str, snapshot.val()]);
});
});
})).then(function (results) {
return results.reduce(function (result, item) {
var key = item[0],
value = item[1];
result[key] = value;
return result;
}, {});
});
}
每个承诺现在都解析为一个数组,基本上[键,值]
.then after Promise.all将所有这些结果组合到一个对象中,如:{key1:value1,key2:value2,
上面的代码使用了。once('value')
而不是。on('value'
)-正如评论中指出的,使用。on
会让听者附加。因为承诺只能解决一次,所以使用。once
Jaromanda精心设计的答案的这一微小变化利用了DataSnapshot的特性(这一切都归功于他的设计):
Jaromanda精心设计的答案的这一微小变化利用了DataSnapshot的特性(这一切都归功于他的设计):
谢谢。我会看看我是否可以调整一些。谢谢。我会看看我是否可以调整一些。谢谢你花时间把这些整合起来。
on()
让监听器保持连接。不应该一次()
是否在此处使用?无。速记箭头函数以这种方式传输,因为它们就是这样做的。返回是多余的。感谢您花时间将这些内容组合在一起。on()
使侦听器保持连接。不应该一次()
是否在此处使用?无。速记箭头函数以这种方式传输,因为它们就是这样做的。返回是多余的