代码之家  ›  专栏  ›  技术社区  ›  JurgR

Firebase函数-使用async/await with once()函数

  •  1
  • JurgR  · 技术社区  · 6 年前

    我对typescript还很陌生,到目前为止我一直在使用它,但我发现了一个奇怪的错误/bug,我无法用async/await解决它。

    我有以下代码片段,我的问题是“await”子句不能与一起使用。once()函数。

    async function testFunction(deviceID:string){
        const returnObject:{name:string, description:string, tokens:string[]}[] = [];
    
        const deviceRef = admin.database().ref('deviceInfo/').orderByChild('id').equalTo(deviceID);
    
        await deviceRef.once('value', async (payload) => {
            const pushObject:{name:string, description:string, tokens:string[]} = {name:"", description:"", tokens:[]};
            if(payload.exists()){
                const devices = payload.val();
                const keys = Object.keys(devices);
    
                for(const key of keys){
                    pushObject.name = devices[key].name;
                    pushObject.description = devices[key].description;
                    pushObject.tokens = await getTokens(key);
                    returnObject.push(pushObject);
    
                }
                console.log("Return Object 1:", returnObject);
                return returnObject;
    
            }
            else{
                return null;
            }
    
        })
        console.log("Return Object 2:", returnObject);
        return returnObject;
    }
    

    此函数始终返回{name:,description:,tokens:[]},即使我在deviceRef的开头有“await”。once()函数。

    也包括两个控制台。logs print,“Return Object 1”使用从DB检索到的所有数据打印正确的对象,但“Return Object 2”打印空数组。所以很明显,await并不是在等待once()函数完成,我只是不知道为什么会这样?

    如有任何帮助或建议,将不胜感激

    1 回复  |  直到 6 年前
        1
  •  2
  •   Doug Stevenson    6 年前

    使用once()时,可以选择以下两个选项之一:

    1. 使用返回的承诺从查询中获取数据。
    2. 传递回调函数作为第二个参数,以从查询中获取数据。

    如果要使用async/await,我会选择选项1。现在看起来您正在使用1和2的组合。如果要使用once()返回的承诺,请不要麻烦地将回调函数传递给once()。这有点违背了使用异步/等待的目的。

    const payload = await deviceRef.once('value')
    if (payload.exists()) { ... }