首页 > 解决方案 > (JavaScript) 返回未定义值的函数

问题描述

我有一个从 Firebase 数据库读取的函数,它会返回它找到的关于用户的任何数据。

授权.js:

const login = (db, token) => {
    db.collection('users').get().then(async (e) => {
        var i = []
        e.forEach(async (doc) => {
            if (doc.data().access_token === token){
                i.push(doc.data().id)
                return doc.data()
            }
        })
        if (i.length === 0) return false
    }).catch((error) => {
        return false
    })
}
module.exports = login

应用程序.js:

app.post('/token/:token', async (req, res) => {
    res.send(await login(db, req.params.token))
})

authorize.js中,我发现了错误,但不记录它。当我console.log()直接在函数内部返回的值时,不会发生错误,它给了我想要的结果。

标签: javascriptnode.js

解决方案


您缺少两个returns。此外,您在其中有该函数,e.forEach async这意味着它将在您的其余代码之后运行,因此您将无法获得结果,请将其删除(因为无论如何您都没有在其中执行任何异步操作):

const login = (db, token) => {
    // v HERE v - you need to return the promise
    return db.collection('users').get().then(async (e) => {
        var i = []
        // v HERE v - no async
        e.forEach((doc) => {
            if (doc.data().access_token === token){
                i.push(doc.data().id)
                // Also, no need for a return here, since it doesn't do anything
            }
        })
        if (i.length === 0) return false
        return i // << instead, here was another return missing
    }).catch((error) => {
        return false
    })
}
module.exports = login

更清晰的方法是 make ,然后你也可以在login那里使用:asyncawait

async function login (db, token) {
    try {
        const e = await db.collection('users').get()
        const i = []

        for (const doc of e) {
            if (doc.data().access_token === token){
                i.push(doc.data().id)
            }
        }

        if (i.length === 0) return false
        return i
    } catch (e) {
        return false
    }
}

module.exports = login

这可以进一步简化:

async function login (db, token) {
    try {
        const matchingUserIds = await db.collection('users').get()
            .map(doc => doc.data())
            .filter(docData => docData.access_token === token)
            .map(docData => docData.id)

        return matchingUserIds.length ? matchingUserIds : false
    } catch (e) {
        return false
    }
}

module.exports = login

(我想知道是否没有更好的方法可以通过数据库中的访问令牌过滤用户。现在看来您将获取所有用户,然后在此函数中检查令牌;它可能更具可扩展性首先通过令牌查询数据库。)


推荐阅读