javascript - NodeJS 从多个 http 请求中获取数据

标签 javascript node.js

我有一个 API,当触发它发送 2 个 HTTP Get 请求时

我想从第一个 Get Request 获取响应并将其存储在一个变量中

所以我可以将它与第二个获取请求的响应一起发送。实现它的最佳方法是什么

这是我尝试做的

    dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    getRequest(memberLastLoginURL)
        .then(response => {
            let lastLoginTime = response.data.result
        })
        .catch(errorMessage => {
            console.log( 'Member Last Login API ERROR: ' + errorMessage)
            res.json(errorMessage)
        });
    getRequest(memberProfileStatsURL)
        .then(response => {
            let stats = response.data.result
            let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
            let totalPoints = stats.totalPoints
            res.json({
                data: {
                    totalPoints: stats.totalPoints,
                    totalPointsRedeemed: stats.totalPointsRedeemed,
                    availablePoints: (stats.totalPoints - stats.totalPointsRedeemed),
                    totalSessionTime: secondsToHm(stats.totalSessionTime), //convert sessionTime seconds to hours
                    loginsCount: stats.totalSessions,
                    rank: rank(totalPoints, pointsRank),
                    createdTime: stats.created,
                    lastLoginTime: lastLoginTime,
                },
                result: response.data.httpStatusCode
            })
        })
        .catch(errorMessage => {
            res.json(errorMessage)
        });
})

但我得到 lastLoginTime 未定义

最佳答案

如果您希望请求并行运行,您可以同时启动它们,然后使用 Promise.all 等待它们。 .然后,当两者都完成后,使用它们的结果来发送响应:

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    // *** Start the requests in parallel
    Promise.all([
        getRequest(memberLastLoginURL)
            .then(response => {
                return response.data.result
            }),
        getRequest(memberProfileStatsURL)
            .then(response => {
                return response.data.result // *** If this is a common thing, consider a wrapper
            })                              //     function for `getRequest` so we don't have to
    ])                                      //     re-write this fulfillment handler repeatedly
    .then(([lastLoginTime, memberStats]) => {
        // *** Both are done, send response
        let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
        let totalPoints = memberStats.totalPoints
        res.json({
            data: {
                totalPoints: memberStats.totalPoints,
                totalPointsRedeemed: memberStats.totalPointsRedeemed,
                availablePoints: (memberStats.totalPoints - memberStats.totalPointsRedeemed),
                totalSessionTime: secondsToHm(memberStats.totalSessionTime), //convert sessionTime seconds to hours
                loginsCount: memberStats.totalSessions,
                rank: rank(totalPoints, pointsRank),
                createdTime: memberStats.created,
                lastLoginTime: lastLoginTime,
            },
            result: 200 // *** Presumably this is 200 (or 200 is close enough), since this is a successful response
        })
    })
    .catch(errorMessage => {
        console.log( 'You'll want to update this error message: ' + errorMessage)
        res.json(errorMessage)
    })
})

请注意,Promise.all 的 promise 会以结果数组的形式实现,结果的顺序与输入 promise 的顺序相同。


请注意,在上面它发送了 200,具体而言,而不是 response.data.httpStatusCode 用于 result。但是,如果您确实需要来自 memberProfileStatsURL 调用的 response.data.httpStatusCode,您可以像这样将它传递给最终的执行处理程序:

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    // *** Start the requests in parallel
    Promise.all([
        getRequest(memberLastLoginURL)
            .then(response => {
                return response.data.result
            }),
        getRequest(memberProfileStatsURL)
            .then(response => {
                return {memberStats: response.data.result, httpStatusCode: response.data.httpStatusCode};
            })
    ])
    .then(([lastLoginTime, {memberStats, httpStatusCode}]) => {
        // *** Both are done, send response
        let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
        let totalPoints = memberStats.totalPoints
        res.json({
            data: {
                totalPoints: memberStats.totalPoints,
                totalPointsRedeemed: memberStats.totalPointsRedeemed,
                availablePoints: (memberStats.totalPoints - memberStats.totalPointsRedeemed),
                totalSessionTime: secondsToHm(memberStats.totalSessionTime), //convert sessionTime seconds to hours
                loginsCount: memberStats.totalSessions,
                rank: rank(totalPoints, pointsRank),
                createdTime: memberStats.created,
                lastLoginTime: lastLoginTime,
            },
            result: httpStatusCode
        })
    })
    .catch(errorMessage => {
        console.log( 'You'll want to update this error message: ' + errorMessage)
        res.json(errorMessage)
    })
})

关于javascript - NodeJS 从多个 http 请求中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59663667/

相关文章:

javascript - 使用模数按字母顺序对列表进行排序

javascript - Express app.get : req. body返回值的类型而不是实际值

node.js - npm install 不会安装 devDependencies

node.js - MongoDB 聚合与 Mongoose 虚拟

node.js - 如何导出具有多个静态方法的类

javascript - 如何在工具栏之外使用免费的 jqgrid 搜索和查看工具栏按钮

javascript - 如何在 jQuery 中使用随机数组输出作为 for-loop CSS 属性

javascript - javascript中 ionic 改变进度条条颜色

javascript - 文件上传完成后如何将 uploadcare 小部件重置为原始状态

node.js - createWriteStream 和绝对路径不起作用