(JavaScript)函数返回未定义的值

时间:2020-04-24 23:06:03

标签: javascript node.js

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

authorize.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

app.js:

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

authorize.js中,我捕获了错误,但是没有记录下来。当我console.log()直接在函数内部返回的值时,没有错误发生,它给了我想要的结果。

2 个答案:

答案 0 :(得分:2)

您缺少两个return。另外,您在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

更清晰的方法是将login也设置为async,然后您也可以在其中使用await

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

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

答案 1 :(得分:0)

异步函数总是伴随着等待,并且在函数内部没有看到任何等待。

更清晰。