javascript - promise 不等待异步对象条目 firebase 调用

标签 javascript firebase asynchronous promise

我有一个 main 函数等待并并行连接几个函数,如下所示:

主要功能:

console.log('A');
const pivotData = await Promise.all(
    Object.entries(thenWidgets.val()).map(widget => {
      getPivot(widget, userId)
      console.log('B');
    });
);
console.log('C');
console.log('D');
const mainData = await Promise.all(
    pivotData.map(widget => getMain(widget))
);
console.log('F');
mainData.map(item => {
    return (finalObject[item.widgetId] = item);
});
console.log('G');

在遇到 console.log('D') 下方的 mainData 之前,一切正常。它似乎不等待 promise 并直接跳到 console.log('F') 而无需等待保存 console.log('E')

getMain() 函数:

const getMain = widget => {
  return new Promise(resolve => {
    var requests = [];
      const pivotData = {};
        Object.keys(widget.pivot).map(item => {
          const mainRef = firebase
            .database()
            .ref()
            .child(widget['default'].type)
            .child(item);

          mainRef.once('value', snapMain => {
            pivotData[item] = snapMain.val();
          }).then(() => {
            widget['main'] = pivotData;
            console.log('E');
            requests.push('test');
          });
          console.log('E2')
        })
        Promise.all(requests)
        .then(() => {
          console.log('E3');
          resolve(widget);
        })
        .catch(error => console.log(`Error in promises ${error}`));
  });
};

这里的预期结果是:'E, E2, E, E2, E3' 但我得到的是 'E2, E2, E3' 然后它返回了 promise 。后来,在所有 promise 都解决之后的某个地方,我得到了“E,E”。所以整个事情的预期结果应该是'A,B,C,D,E,E2,E,E2,E3,F,G'我现在拥有的是'A,B,C,D,E2,E2 , E3, F, G, E, E'

getMain() 中的Object.keys 中的promise 似乎没有等待mainRef.once。也许我错过了什么。

我的问题是:promise 不等待 getMain() 函数是怎么回事?

最佳答案

让我们仔细看看 getMain 函数,特别是 console.log('E') 周围的行。这里发生的事情如下:

  1. 在这里你调用 Firebase,.once(...) 返回一个不是 await 的 promise,所以它稍后会得到解决, getMain 返回之后
  2. 由于 promise 不是 await-ed,下一行要执行的是 console.log('E2') 然后继续下一次迭代循环
  3. 循环结束后,requests 将是一个空数组(因为值应该来自 .once(...) 处理程序,但我们从未等待在这些 promise 上)。空数组立即得到解析,因此 Promise.all(requests) 落入 then 部分,注销“E3”并解析主要 promise ,有效地返回原始小部件
  4. 一旦 getMain 返回,我们之前创建的 promise 将开始“在幕后”解析和修改小部件,因此下次您尝试对小部件执行任何操作时,您可能会发现一些完整的东西出乎意料。

为了修复此功能,您需要等待 Firebase 返回的 promise before 继续底部的主要 promise - 您可以通过将 的结果.once() 调用一个新数组并在该数组上调用 Promise.all(...),或者通过在循环的每次迭代中编写一个“链式”promise 然后等待在循环之后就可以了

希望对您有所帮助!

关于javascript - promise 不等待异步对象条目 firebase 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59212707/

相关文章:

firebase - 通过 Firebase 仪表板(或 cli)禁用 Firebase 的云功能

快速在 UITableView 中异步加载图像 - 顶部单元格没有图片

javascript - jQuery 动画卡顿

ios - 找不到协议(protocol)声明 'FIRMessagingDelegate'

javascript - 尝试使用 Aurelia 插件导致浏览器出现 404 错误

node.js - 等待不是等待

mysql - 使用异步等待插入每个

javascript - 下划线 : sortBy() based on multiple attributes

javascript - 如何在 chartjs 中显示直 Angular

javascript - jQuery 添加自定义密码规则不起作用