Firebase数据与javascript的异步承诺相结合
我声明了一个函数,用于异步获取Firebase数据。函数必须等待所有数据放入对象中。出于某种原因,该函数将继续执行,而无需等待对象设置完成Firebase数据与javascript的异步承诺相结合,javascript,firebase,firebase-realtime-database,promise,Javascript,Firebase,Firebase Realtime Database,Promise,我声明了一个函数,用于异步获取Firebase数据。函数必须等待所有数据放入对象中。出于某种原因,该函数将继续执行,而无需等待对象设置完成 /** Get the data content */ const getData = async (widget, userId) => { let promises = []; let mainObject = {}; const pivotData = {}; const pivotName = 'user' + widg
/** Get the data content */
const getData = async (widget, userId) => {
let promises = [];
let mainObject = {};
const pivotData = {};
const pivotName =
'user' + widget[1].type.charAt(0).toUpperCase() + widget[1].type.slice(1);
//Object entries
mainObject = {
default: widget[1],
};
mainObject['widgetId'] = widget[0];
//Main listner
const mainRef = firebase
.database()
.ref()
.child(widget[1].type);
//Pivot Listner
const pivotRef = firebase
.database()
.ref()
.child(pivotName)
.child(userId);
//Set promise
promises.push(
new Promise(async resolve => {
pivotRef
.once('value', snapPivot => {
snapPivot.forEach(function(result) {
if (result.val().widgetId === widget[0]) {
pivotData[result.key] = result.val();
mainObject['pivot'] = pivotData;
mainObject['typeId'] = result.key;
mainObject['main'] = {};
console.log('1');
mainRef.child(result.key).once('value', snapshot => {
console.log('2');
mainObject['main'][result.key] = snapshot.val();
});
}
});
})
.then(() => {
resolve();
console.log('3');
});
})
);
Promise.all(promises).then(results => {
return mainObject;
});
};
console.logs的预期结果为1,2,3,但显示为1,1,3,2
为什么函数没有在循环中等待
.once
函数?问题在于您没有等待mainRef.child(result.key).once()的承诺来解决
此外,在调用mainRef.child(result.key).once()时,您只需将一个承诺推送到您希望推送到的承诺数组中
使用等待承诺.all()
//Reference.once返回承诺
const dataSnapshot=await pivotRef.once('value');
让承诺=[];
dataSnapshot.forEach((结果)=>{
const key=result.key;
const data=result.val();
if(data.widgetId==widget[0]){
数据透视数据[键]=数据;
mainObject['pivot']=数据透视;
mainObject['typeId']=键;
mainObject['main']={};
console.log('1');
const promise=mainRef.child(result.key)
.once('value',快照=>{
console.log('2');
mainObject['main'][result.key]=snapshot.val();
});
//将承诺添加到我们的承诺数组中
承诺。推动(承诺);
}
});
//等待所有承诺实现(即解决)
等待承诺。所有(承诺);
//假设3只需要记录一次(最后)
console.log('3');
console.log(main对象);
返回主对象;
让我知道这是否有效 问题在于您没有等待mainRef.child(result.key).once()的承诺来解决 此外,在调用mainRef.child(result.key).once()时,您只需将一个承诺推送到您希望推送到的承诺数组中 使用
等待承诺.all()
//Reference.once返回承诺
const dataSnapshot=await pivotRef.once('value');
让承诺=[];
dataSnapshot.forEach((结果)=>{
const key=result.key;
const data=result.val();
if(data.widgetId==widget[0]){
数据透视数据[键]=数据;
mainObject['pivot']=数据透视;
mainObject['typeId']=键;
mainObject['main']={};
console.log('1');
const promise=mainRef.child(result.key)
.once('value',快照=>{
console.log('2');
mainObject['main'][result.key]=snapshot.val();
});
//将承诺添加到我们的承诺数组中
承诺。推动(承诺);
}
});
//等待所有承诺实现(即解决)
等待承诺。所有(承诺);
//假设3只需要记录一次(最后)
console.log('3');
console.log(main对象);
返回主对象;
让我知道这是否有效 您没有等待mainRef.child(result.key)的承诺。一次解决-这就是为什么您会在本文档中获取日志order@bastien我需要在那里输入什么样的承诺?您是否希望结果存储在承诺数组中,并在函数结束时返回?是的,我需要返回将发送到react应用程序的Main对象。如果mainObject需要存储在数组中,这不是问题。Promissions数组用于什么?您没有等待mainRef.child(result.key)的承诺。一次解决-这就是为什么您会在本文档中获取日志order@bastien我需要在那里输入什么样的承诺?您是否希望结果存储在承诺数组中,并在函数结束时返回?是的,我需要返回将发送到react应用程序的Main对象。如果main对象需要存储在数组中,这不是问题。数组的用途是什么?
// Reference.once returns a promise Promise<DataSnapshot>
const dataSnapshot = await pivotRef.once('value');
let promises = [];
dataSnapshot.forEach((result) => {
const key = result.key;
const data = result.val();
if (data.widgetId === widget[0]) {
pivotData[key] = data;
mainObject['pivot'] = pivotData;
mainObject['typeId'] = key;
mainObject['main'] = {};
console.log('1');
const promise = mainRef.child(result.key)
.once('value', snapshot => {
console.log('2');
mainObject['main'][result.key] = snapshot.val();
});
// add promise to our promises array
promises.push(promise);
}
});
// wait for all the promises to be fulfilled (i.e resolved)
await Promise.all(promises);
// assuming 3 only needs to be logged once (at the end)
console.log('3');
console.log(mainObject);
return mainObject;