Node.js 请求函数返回数据

问题描述 投票:0回答:2

我已经解决了有关从节点 JS 请求调用返回数据的问题。一个常见的错误是假设语句是逐行或同步执行的,但这里的情况并非如此。此类问题:如何从 Node.js http get 请求中获取数据

我的问题有点不同。我编写了一个函数 getNumber() ,它返回给定查询的结果数。我想知道如何返回回调函数检索到的值?例如:

function getNumResults() { 

Request(url, function(response) { 

    var responseJSON = JSON.parse(body); 
    return(responseJSON.results.count); 

   }); 

}

function Request(URL, callback) {

request(URL,  function(error, response, body) { 

    console.log('URL: ', URL); 
    console.log('error: ', error); 
    console.log('statusCode: ', response && response.statusCode); 
    console.log('body: ', body); 
    callback(body); 
}); 

}

如果我希望 getNumResults() 返回 responseJSON.results.count 怎么办?我怎么能这样做呢?

node.js request httprequest
2个回答
4
投票

如果我希望 getNumResults() 返回 responseJSON.results.count 怎么办?我怎么能做到这一点?

您不能直接从

getNumResults()
返回异步值。你就是不能。该函数早在该值可用之前就返回了。这是一个时间问题。这就是异步响应的工作原理。它们会在未来某个不确定的时间完成,但它们是非阻塞的,因此 Javascript 的其余部分会继续运行,因此函数会在结果可用之前返回。

获取结果的唯一方法是使用某种回调。这适用于您的

Request()
函数和我们的
getNumResults()
函数。一旦结果是异步的,调用链中的任何人都无法逃避这一点。异步具有传染性,你永远无法从异步回到同步。因此,如果您的
getNumResults()
想要将值返回给其调用者,它要么必须本身接受回调并在获取值时调用该回调,要么必须返回一个用该值解析的承诺。

以下是如何使用 Promise 来做到这一点(这是 Javascript 异步开发的未来):

// load a version of the request library that returns promise instead of
// taking plain callbacks
const rp = require('request-promise');

function getNumResults(url) {
    // returns a promise
    return rp(url).then(body => {
        // make the count be the resolved value of the promise
        let responseJSON = JSON.parse(body);
        return responseJSON.results.count;
    });
}

然后,你可以像这样使用

getNumResults()

getNumResults(someURL).then(count => {
    // use the count result in here
    console.log(`Got count = ${count}`);
}).catch(err => {
    console.log('Got error from getNumResults ', err);
});

仅供参考,如果您愿意,我认为您还可以通过设置适当的选项来获取

request()
库来自动解析您的 JSON 响应
{json: true}


编辑 2020 年 1 月 - request() 模块处于维护模式

仅供参考,

request
模块及其衍生物(如
request-promise
)目前处于维护模式,不会积极开发以添加新功能。您可以在here阅读更多有关推理的信息。 此表中有一个替代方案列表,并对每个方案进行了一些讨论。我自己一直在使用
got()
,它从一开始就使用 Promise 构建,并且使用起来很简单。


0
投票

2023 年,我写了 sync-request-curl。该库将帮助使用 libcurl 的 Easy 界面发送同步 HTTP 请求。

该库包含原始 sync-request 中功能的子集,但利用 node-libcurl 以获得更好的性能和 NodeJS 的附加 libcurl 选项。

这是 GET 请求的简单用法:

// import request from 'sync-request-curl';
const request = require('sync-request-curl');
const response = request('GET', 'https://ipinfo.io/json');
console.log('Status Code:', response.statusCode);
console.log('body:', response.body.toString());
console.log('json:', JSON.parse(response.body.toString());

具体到您的问题,您可以按如下方式重写代码:

const request = require('sync-request-curl');

const getNumResults = (url) => { 
  const response = request('GET', url);
  const json = JSON.parse(response.body.toString());
  return json.results.count;
};

也可以处理错误,你可以这样做

const request = require('sync-request-curl');

const getNumResults = (url) => { 
  try {
    const response = request('GET', url);
    if (response.statusCode !== 200) {
      throw new Error(`GET Request fails with status ${response.statusCode}`);
    }
    // Error if response.body.toString() is not a JSON, e.g. server returns HTML
    const json = JSON.parse(response.body.toString());
    return json.results.count;
  } catch (error) {
    // handle error
  }
};

希望这有帮助:)。

© www.soinside.com 2019 - 2024. All rights reserved.