Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引用错误,表示未定义变量_Javascript_Firebase_Firebase Realtime Database - Fatal编程技术网

Javascript 引用错误,表示未定义变量

Javascript 引用错误,表示未定义变量,javascript,firebase,firebase-realtime-database,Javascript,Firebase,Firebase Realtime Database,所以我有一个函数,它从Firebase数据库读取数据,然后创建一个对象数组。我已经定义了变量键,但它仍然不可用 var usersList = []; const ref = firebase.database().ref() function fetchUsers() { ref.child('users').once('value').then(snap => { var promises = []; snap.forEach(child

所以我有一个函数,它从Firebase数据库读取数据,然后创建一个对象数组。我已经定义了变量
,但它仍然不可用

var usersList = [];

const ref = firebase.database().ref()

function fetchUsers() {

    ref.child('users').once('value').then(snap => {
        var promises = [];

        snap.forEach(childSnap => {

            var key = childSnap.key

            promises.push
                (ref.child(`users/${key}/points`).once('value')
            );


        });

        return Promise.all(promises);

    }).then(function(snapshots) {
        return snapshots.map(snapper => {
        var points = snapper.val()
        return {uid: key, points: points};
        })
    }).then(function(usersList) {
        console.log(usersList)
    })

}
这就是我得到的错误

(node:11724) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: key is not defined

如果我只是这样做:
key=childSnap.key
,那么每个对象的
uid
都是相同的。

key
仅在
forEach
回调中定义。当然,您不能在第二次
然后
回调中引用它。此外,它将是哪个
?第一次入境?第二个?第三

相反,您需要返回具有以下值的键:

function fetchUsers() {
    ref.child('users').once('value').then(snap => {
        var promises = [];
        snap.forEach(childSnap => {
            var key = childSnap.key;
            promises.push(
                ref.child(`users/${key}/points`).once('value').then(
                    snapper => ({key, snapper})    // **
                )
            );
        });

        return Promise.all(promises);
    }).then(function(snapshots) {
        return snapshots.map(({key, snapper}) => { // **
            var points = snapper.val();
            return {uid: key, points: points};
        });
    }).then(function(usersList) {
        console.log(usersList);
    });
}
在上面的第一行
**
中,我们将转换
的结果一次
,这样它将返回一个包含键和“snaper”的对象

在第二行
**
中,我们使用解构参数来接收这些对象作为distinct
snaper
参数


FWIW,如果您想积极使用简明箭头:

function fetchUsers() {
    ref.child('users').once('value').then(snap =>
        Promise.all(snap.map(childSnap => {
            const key = childSnap.key;
            return ref.child(`users/${key}/points`)
                        .once('value')
                        .then(snapper => ({key, snapper}));
        }))
    ).then(snapshots =>
        snapshots.map(({key, snapper}) => ({uid: key, points: snapper.val()}))
    ).then(usersList => {
        console.log(usersList);
    });
}

还要注意使用
map
,而不是声明数组并从
forEach
回调推送到它。:-)

我强烈建议深入学习,
是必需的。(这很简单:在每个语句的末尾都没有被附加到语句的块终止。因此在
x=function(){};
之后,因为块附加到表达式,而不是语句;而不是在
之后(…){}
因为块附加到语句。)然后,您可以在知情的情况下选择是使用它们,还是依赖JavaScript内置的“自动分号插入”纠错机制。在上面的例子中,您一半是提供它们,一半是依赖ASI。另外,如果不需要
函数
函数,建议您始终优先使用箭头函数而不是
函数。非常感谢!我考虑了你的建议。