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

Javascript 如何等待request.get完成,然后在node.js中执行下一个块,javascript,node.js,express,request,Javascript,Node.js,Express,Request,我是NodeJS的新手,正在处理一个请求。获取问题。我的目标只是拥有一个请求web的函数,当请求完成时,该函数返回结果,否则返回错误消息 以下是我用于请求的函数: var artistNameIdMap = {}; var getPopularArtists = async () => { //https://nodejs.org/api/http.html#http_http_request_options_callback var options = {

我是NodeJS的新手,正在处理一个
请求。获取
问题。我的目标只是拥有一个请求web的函数,当请求完成时,该函数返回结果,否则返回错误消息

以下是我用于请求的函数:

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
}
这个函数包含在
getPopular.js
文件中。我想调用另一个文件
playlist.js
中的函数

在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
既然你想使用承诺,就这样使用它吧

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

或者,如果没有承诺,您需要使用
回调

使用回调:

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

既然你想用承诺,就这样用吧

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

或者,如果没有承诺,您需要使用
回调

使用回调:

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()。第二,有一份推荐的替代方案清单。第三,所有这些替代方案都以本机方式支持承诺,因为这是现代nodejs编程中编写异步代码的首选方式

我最喜欢的替代方案是因为我发现它的界面简单、干净,并且具有我需要的功能。下面是使用
get()
时代码的简单程度:

注意:调用方应根据返回的承诺提供错误处理

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

虽然你已经接受了答案,但我还可以补充几点。首先,
request()。第二,有一份推荐的替代方案清单。第三,所有这些替代方案都以本机方式支持承诺,因为这是现代nodejs编程中编写异步代码的首选方式

我最喜欢的替代方案是因为我发现它的界面简单、干净,并且具有我需要的功能。下面是使用
get()
时代码的简单程度:

注意:调用方应根据返回的承诺提供错误处理

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

首先,
getpopularists
返回一个承诺,因为它是
async
。。。其次,在不等待
请求的情况下返回并解析承诺。get
回调。。。使函数
async
不会神奇地让它等待异步代码完成,并以某种方式提取回调中返回的值-async/await用于处理承诺,exclusively@Bravo谢谢回复!我删除了
async
,现在我得到了
外部{}内部
。如何修改代码以获取
请求。获取
回调?仅供参考,
请求
库已被弃用,不建议您将其用于新代码。你可以在这里看到一个。该列表中我最喜欢的是
get()
,该列表中的所有选项都支持本机承诺,这是nodejs中编写异步操作的首选方式。首先,
getpopulartitists
返回一个承诺,因为它是
async
。。。其次,在不等待
请求的情况下返回并解析承诺。get
回调。。。使函数
async
不会神奇地让它等待异步代码完成,并以某种方式提取回调中返回的值-async/await用于处理承诺,exclusively@Bravo谢谢回复!我删除了
async
,现在我得到了
外部{}内部
。如何修改代码以获取
请求。获取
回调?仅供参考,
请求
库已被弃用,不建议您将其用于新代码。你可以在这里看到一个。我最喜欢的是
get()
该列表中的所有选项都支持本机承诺,这是目前在nodejs中编写异步操作代码的首选方式。我添加了一个非承诺版本@IsaKyodo-如果您想看看它会是什么样子-我还对
response.statusCode==200的情况下的逻辑做了一些更改我已经添加了一个非承诺版本@IsaKyodo-如果你想看看它会是什么样子-我还对
response.statusCode===200
为假的情况下的逻辑做了一些更改。是的,非常感谢!逻辑非常清晰,在
请求.get()中没有嵌套的
(错误、响应、主体)=>{…}
函数。但是要处理
wait-get(url,options).json()的错误
,我是否应该直接对
结果的属性或方法进行
if/else
判断?@IsaKyodo-在我看来,在这个函数中处理错误是没有意义的。您没有在此函数中处理成功,通常应在同一调用级别发送错误响应和成功响应。如果您想在本地处理错误,可以使用
try/catch
包围
wait
。在这里编写代码时,一个错误将导致返回的承诺被拒绝,这是您应该捕获它的地方,因此您可以在同一级别处理成功和错误。@IsaKyodo-如果需要,您当然可以在
结果
上执行
,但是
get()中的错误
例如非2xx返回状态将作为拒绝承诺自动抛出(另一件事是
get()
自动为您做的)。因此,如果我想处理调用方中的错误,