简体   繁体   English

如何等到 request.get 完成然后在 node.js 中执行下一个块

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

I am new to NodeJS and I am working on a request.get problem.我是 NodeJS 的新手,我正在处理request.get问题。 My goal is simply have a function that request the web, and when request finished, the function returns the result, otherwise it returns an error message.我的目标只是有一个请求 web 的 function,当请求完成时,function 返回结果,否则返回错误消息。

Here's the function that I used for request:这是我用于请求的 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
}

And this function is included in a getPopular.js file.这个 function 包含在getPopular.js文件中。 I would like to call the function in another file playlist.js .我想在另一个文件playlist.js中调用 function 。

In playlist.js , I wroteplaylist.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);
})

However the result I got is但是我得到的结果是

outside
Promise { {} }
inside

It seems like the return was before the request gives back the information.似乎返回是在请求返回信息之前。 I wonder what should I write to make sure that I can obtain the correct artistNameIdMap at playlist.js .我想知道我应该写什么来确保我可以在playlist.js获得正确的artistNameIdMap

Since you want to use Promises, use it like this既然要使用 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
}

And use it like并像使用它一样

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);
    }
})

Alternatively, without promises, you'll need to use a callback或者,如果没有承诺,您将需要使用callback

Using callbacks:使用回调:

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
}

And use it like:并像这样使用它:

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);
        }
    });
});

Though you've already accepted an answer, there are a couple of additional things I can add.尽管您已经接受了答案,但我还可以添加一些其他内容。 First, the request() library has been deprecated and it is not recommended for new code.首先, request()库已被弃用,不推荐用于新代码。 Second, there is a list of recommended alternatives here .其次,这里有一个推荐替代品列表。 Third, all these alternatives support promises natively as that is the preferred way to program asynchronous code in modern nodejs programming.第三,所有这些替代方案都原生支持 Promise,因为这是在现代 nodejs 编程中编写异步代码的首选方式。

My favorite alternative is got() because I find it's interface simple and clean to use and it has the features I need.我最喜欢的替代方法是got() ,因为我发现它的界面简单明了,并且具有我需要的功能。 Here's how much simpler your code would be using 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
}

Note: The caller should supply error handling based on the returned promise.注意:调用者应根据返回的 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