关于Nodejs 获取 Request 返回数据的问题

关于Nodejs 获取 Request 返回数据的问题

# api.js
exports.getData = function(req, res) {
request({uri: ‘api.example.com’, headers: HEADERS}, function(error, response, body) {
if(!error && response.statusCode == 200) {
res.send(body); // body 是 JSON 数据.
}
else {
res.send(error);
}
});
};
# app.js
router.get(’/xxx’, function(req, res){
var data = api.getData(req, res);
//var data_obj = JSON.parse(data);
console.log(data);
});

在 app.js 里调用 getData 函数,此时 data 的返回值为 undefined!

试验方案二: 把它改为一般的函数调用形式,

# api.js
exports.getData = function() {
	return request(..., function(){
		return body;
	});
};
# app.js
router.get('/xxx', function(req, res){
	var data = api.getData();
	//var data_obj = JSON.parse(data);
	console.log(data);
});

此时的 data 返回值为 http 协议相关的信息,并不是我期望的 request 返回值 body.

请问:

  1. 怎样正确获取到 getData 函数的返回值?
  2. 请解释下为什么 data 返回值为 undefined ?
  3. 这个问题涉及到 JS 的哪个知识点?JS 回调函数机制? 望各位提点一下,我去查阅相关知识点。

谢谢。


5 回复

关于Nodejs 获取 Request 返回数据的问题

在 Node.js 中处理异步操作时,特别是涉及到网络请求时,使用回调函数是一个常见的模式。让我们来看一下你的代码并分析问题所在。

1. 为什么 data 返回值为 undefined

在你提供的第一个代码片段中,getData 函数内部使用了 request 模块来发送 HTTP 请求。由于 HTTP 请求是异步的,所以 getData 函数会立即返回,而不会等待请求完成。因此,在 app.js 中直接调用 getData 并不能获取到请求的结果,因为请求尚未完成。

# api.js
exports.getData = function(req, res) {
  request({uri: 'api.example.com', headers: HEADERS}, function(error, response, body) {
    if (!error && response.statusCode == 200) {
      res.send(body); // body 是 JSON 数据.
    } else {
      res.send(error);
    }
  });
};
# app.js
router.get('/xxx', function(req, res){
  var data = api.getData(req, res);
  console.log(data); // data 为 undefined
});

2. 如何正确获取到 getData 函数的返回值?

为了正确处理异步操作,可以使用回调函数、Promise 或 async/await。这里我们使用 Promise 来重构代码:

# api.js
const rp = require('request-promise');

exports.getData = function() {
  return rp({
    uri: 'api.example.com',
    headers: HEADERS,
    json: true // 解析 JSON 数据
  });
};
# app.js
router.get('/xxx', function(req, res){
  api.getData()
    .then(data => {
      console.log(data); // 此处可以处理返回的数据
      res.send(data);
    })
    .catch(error => {
      console.error(error);
      res.status(500).send('Error occurred');
    });
});

3. 这个问题涉及的 JS 知识点是什么?

这个问题主要涉及的是 JavaScript 的 异步编程回调函数机制。在 Node.js 中,许多 I/O 操作(如文件读写、HTTP 请求等)都是异步的,这意味着它们不会阻塞主线程。因此,需要使用回调函数、Promises 或 async/await 来处理这些异步操作的结果。

  • 回调函数:是一种传统的异步编程方式,通过将函数作为参数传递给另一个函数来实现。
  • Promises:提供了一种更清晰的方式来处理异步操作,避免了回调地狱(Callback Hell)。
  • async/await:基于 Promises 的语法糖,使得异步代码看起来更像同步代码,更容易理解和维护。

希望这些解释能帮助你理解如何正确处理异步操作,并解决你的问题。


1.request是异步的,你这样写的话,getData方法里面的参数应该再加一个callback,才能拿到你想要的body吧。 2.你只是声明了data变量,getData并没有任何返回值啊,此时console.log是undefined的

恩,看一个callback的例子,道友就知道怎么写啦:D

看了一下module介绍,api.getData().pipe(process.stdout)应该可以;

要正确获取 getData 函数的返回值,我们需要理解 Node.js 中异步编程的概念。由于 HTTP 请求是异步操作,我们不能直接返回请求的结果。因此,需要使用回调函数来处理异步结果。

示例代码

api.js

const request = require('request'); // 确保你已经安装了 request 包

exports.getData = function (req, res, callback) {
    request({ uri: 'http://api.example.com', headers: HEADERS }, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            callback(null, body); // 正常情况下,第一个参数为 null,第二个参数为返回的数据
        } else {
            callback(error || new Error('Request failed'), null);
        }
    });
};

app.js

const express = require('express');
const router = express.Router();
const api = require('./api');

router.get('/xxx', function (req, res) {
    api.getData(req, res, function (err, data) {
        if (err) {
            console.error(err);
            res.status(500).send("Error occurred");
        } else {
            console.log(data);
            res.send(data);
        }
    });
});

module.exports = router;

解释

  1. 回调函数:在 api.js 中,我们将 getData 函数的第三个参数定义为一个回调函数。当请求完成时,该回调函数将被调用,并传入错误对象(如果有的话)和请求体作为参数。

  2. 异步处理:由于 HTTP 请求是异步的,所以我们不能直接返回请求结果。必须通过回调函数处理异步结果。

  3. 错误处理:在回调函数中,我们检查是否有错误发生。如果有错误,则调用 res.status(500).send("Error occurred") 发送错误信息;否则发送请求体。

问题原因及知识点

  • data 返回值为 undefined:在第一次尝试中,request 是异步的,而 getData 并没有等待请求完成就返回了。因此,data 为空。

  • JS 回调函数机制:这个问题主要涉及 JavaScript 的回调函数机制。JavaScript 异步编程通常使用回调函数来处理异步操作的结果。理解这一点对解决此类问题非常关键。你可以查阅有关 Node.js 异步编程的文章或教程来加深理解。

希望这些解释能帮助你更好地理解问题所在,并解决你的困惑。

回到顶部