【问题标题】:Why is await not working waiting for the code to complete为什么等待不工作等待代码完成
【发布时间】:2019-12-18 09:08:57
【问题描述】:

我正在尝试从 firebase 读取数据。但是代码是异步工作的,它会在获取数据之前显示数据。

我已经发布了我的代码

componentDidMount(){
    var ref2 = database.ref();
    this.getItems(ref2).then((items) => {
        this.getResult(items).then((val) => {
            // why is this val coming empty 
            ToastAndroid.show(JSON.stringify(val), ToastAndroid.SHORT);
        });
    });
  }

getItems = async (ref2) => {
    var items = [];
    await ref2.once('value', snap => {
        snap.forEach((child) => {
            items.push(child.key);
        });
    });

    // this is working fine . items is correctly returned        
    return items;
}
getResult = async (items) => {
    var response = await this.getFinal(items); 
    // this response is empty why 
    return response;
}
getFinal = async (items) => {
    var result = [];
    await items.forEach((key) => {
        ref = database.ref(key);
        ref.once('value', snap => {

            snap.forEach((child) => {
                //val.push(child.val());
                var id = child.key;
                var data = {
                    username: child.val().username,
                    email: child.val().email,
                    name: child.val().name
                };
                result.push({[id]:data});    
            });
        });
    });
    // this result is empty why   
    return result;
}

我希望 val 不为空,结果也不为空

【问题讨论】:

  • 你在方法getFinal中调用await items.forEach...[Array].forEach 不是异步的。另见:stackoverflow.com/a/5050317/2692307
  • 非常感谢您指出这一点。我真的忽略了这部分
  • 您还在等待.once().on().once() 模式在 EventEmitters 上注册事件处理程序——它们不返回 Promise。 Promise 和 EventEmitters 是处理异步程序流的两种不同设计模式。因此await 不适用于.once()

标签: javascript react-native firebase-realtime-database async-await


【解决方案1】:

正如 Lukas 评论的那样,Array.forEach() 不会返回承诺,因此在其上调用 await 并没有任何用处。

然而,DatabaseReference.once() 调用确实返回了一个 promise,并且由于您有多个这样的调用,您可以收集这些 promise 并等待所有这些调用完成,然后再返回结果: p>

getFinal = async (items) => {
    var promises = [],
        result = [];
    items.forEach((key) => {
        ref = database.ref(key);
        let promise = ref.once('value', snap => {
            snap.forEach((child) => {
                var id = child.key;
                var data = {
                    username: child.val().username,
                    email: child.val().email,
                    name: child.val().name
                };
                result.push({[id]:data});    
            });
        });
        promises.push(promise)
    });
    await Promise.all(promises);
    return result;
}

【讨论】:

  • 您的解决方案中缺少result
猜你喜欢
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多