Firebase数据与javascript的异步承诺相结合

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

我声明了一个函数,用于异步获取Firebase数据。函数必须等待所有数据放入对象中。出于某种原因,该函数将继续执行,而无需等待对象设置完成

/** 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;