簡體   English   中英

NodeJS 從多個 http 請求中獲取數據

[英]NodeJS getting data from multiple http requests

我在觸發時有一個 API,它發送了 2 個 HTTP Get 請求

我想從第一個獲取請求中獲取響應並將其存儲在一個變量中

所以我可以將它與第二個獲取請求的響應一起發送。 實現它的最佳方法是什么

這是我嘗試做的

    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的承諾以與輸入其中的承諾相同的順序獲得了一系列結果。


請注意,在上面它發送 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)
    })
})

您正在嘗試訪問lastLoginTime - 其范圍只能在您的第一個 getRequest 內訪問。

由於您想在第二個 getRequest 中使用第一個請求的結果,因此您應該在從第一個 getRequesy 獲得成功響應后執行此操作。 在您的代碼中執行此操作的正確方法是

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
            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)
            });
        })
        .catch(errorMessage => {
            console.log( 'Member Last Login API ERROR: ' + errorMessage)
            res.json(errorMessage)
        });
})

首先,您在承諾中創建變量,因此另一個承諾無法讀取該值。 其次,您需要等待響應。

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, async (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    let lastLoginTime = await getRequest(memberLastLoginURL)
        .then(response => {
            return 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)
        });
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM