簡體   English   中英

如何等到 request.get 完成然后在 node.js 中執行下一個塊

[英]How to wait until request.get finish then conduct the next block in node.js

我是 NodeJS 的新手,我正在處理request.get問題。 我的目標只是有一個請求 web 的 function,當請求完成時,function 返回結果,否則返回錯誤消息。

這是我用於請求的 function:

var artistNameIdMap = {};
var getPopularArtists = async () => {
    //https://nodejs.org/api/http.html#http_http_request_options_callback
    var options = {
        url: CONSTANTS.API_ENDPOINTS.playlist_endpoint + subpath,
        headers: { 'Authorization': 'Bearer ' + access_token,
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'},
        json: true
    }
    
    request.get(options, function(error, response, body) {
        if (response.statusCode === 200){
            console.log("inside");
            artistNameIdMap = getArtistNameIdMap(body, artistNameIdMap);
        } else {
            res.send("get popular error");
            return {};
        }
    })

    console.log("outside");
    return artistNameIdMap;


module.exports = {
    GetPopularArtists: getPopularArtists
}

這個 function 包含在getPopular.js文件中。 我想在另一個文件playlist.js中調用 function 。

playlist.js中,我寫了

const getPopular = require('./controllers/getPopular');
router.get("/BPM/:BPM", (req, res) =>{
    const artistNameIdMap = getPopular.GetPopularArtists();
    console.log(artistNameIdMap);
    let BPM = req.params.BPM;
    res.send(BPM);
})

但是我得到的結果是

outside
Promise { {} }
inside

似乎返回是在請求返回信息之前。 我想知道我應該寫什么來確保我可以在playlist.js獲得正確的artistNameIdMap

既然要使用 Promises,就這樣使用

const getPopularArtists = () => new Promise((resolve, reject) {
    const options = {
        url: CONSTANTS.API_ENDPOINTS.playlist_endpoint + subpath,
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        json: true
    }

    request.get(options, (error, response, body) => {
        if (error) {
            reject(error);
        } else if (response.statusCode === 200) {
            console.log("inside");
            resolve(getArtistNameIdMap(body, artistNameIdMap));
        } else {
            reject("get popular error");
        }
    });
});

module.exports = {
    GetPopularArtists: getPopularArtists
}

並像使用它一樣

const getPopular = require('./controllers/getPopular');
router.get("/BPM/:BPM", async (req, res) =>{
    try {
        const artistNameIdMap = await getPopular.GetPopularArtists();
        console.log(artistNameIdMap);
        let BPM = req.params.BPM;
        res.send(BPM);
    } catch(err) {
        res.send(err);
    }
})

或者,如果沒有承諾,您將需要使用callback

使用回調:

const getPopularArtists = (callback) => {
    const options = {
        url: CONSTANTS.API_ENDPOINTS.playlist_endpoint + subpath,
        headers: { 'Authorization': 'Bearer ' + access_token,
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'},
        json: true
    }
    
    request.get(options, function(error, response, body) {
        if (error) {
            callback(error);
        } else if (response.statusCode === 200){
            console.log("inside");
            callback(null, getArtistNameIdMap(body, artistNameIdMap));
        } else {
            callback("get popular error");
        }
    })
};

module.exports = {
    GetPopularArtists: getPopularArtists
}

並像這樣使用它:

const getPopular = require('./controllers/getPopular');
router.get("/BPM/:BPM", (req, res) =>{
    getPopular.GetPopularArtists((err, artistNameIdMap) => {
        if (err) {
            // handle error here
        } else {
            console.log(artistNameIdMap);
            let BPM = req.params.BPM;
            res.send(BPM);
        }
    });
});

盡管您已經接受了答案,但我還可以添加一些其他內容。 首先, request()庫已被棄用,不推薦用於新代碼。 其次,這里有一個推薦替代品列表。 第三,所有這些替代方案都原生支持 Promise,因為這是在現代 nodejs 編程中編寫異步代碼的首選方式。

我最喜歡的替代方法是got() ,因為我發現它的界面簡單明了,並且具有我需要的功能。 以下是您的代碼使用got()的簡單程度:

const got = require('got');
let artistNameIdMap = {};

async function getPopularArtists() {
    const options = {
        headers: { 'Authorization': 'Bearer ' + access_token,
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'},
    };
    const url = CONSTANTS.API_ENDPOINTS.playlist_endpoint + subpath;
    let results = await got(url, options).json();
    // update local cache object
    artistNameIdMap = getArtistNameIdMap(results, artistNameIdMap);
    return artistNameIdMap;
}

module.exports = {
    GetPopularArtists: getPopularArtists
}

注意:調用者應根據返回的 promise 提供錯誤處理。

GetPopularArtists().then(results => {
    console.log(results);
}).catch(err => {
    console.log(err);
});

暫無
暫無

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

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