gpt4 book ai didi

javascript - Node.js 响应异步数据

转载 作者:行者123 更新时间:2023-11-30 17:10:43 25 4
gpt4 key购买 nike

最近我开始学习一些关于 Node.js 及其功能的知识,并尝试将其用于某些 Web 服务。我想创建一个 Web 服务,作为 Web 请求的代理。我希望我的服务以这种方式工作:

  1. 用户将访问我的服务 -> http://myproxyservice.com/api/getuserinfo/tom
  2. 我的服务将执行请求 -> http://targetsite.com/user?name=tom
  3. 响应的数据将反射(reflect)给用户。

为了实现它,我使用了以下代码:

应用程序.js:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var proxy = require('./proxy_query.js')

function makeProxyApiRequest(name) {
return proxy.getUserData(name, parseProxyApiRequest);
}

function parseProxyApiRequest(data) {
returned_data = JSON.parse(data);
if (returned_data.error) {
console.log('An eror has occoured. details: ' + JSON.stringify(returned_data));
returned_data = '';
}
return JSON.stringify(returned_data);
}

app.post('/api/getuserinfo/tom', function(request, response) {
makeProxyApiRequest('tom', response);
//response.end(result);
});

var port = 7331;

proxy_query.js:

var https = require('https');

var callback = undefined;

var options = {
host: 'targetsite.com',
port: 443,
method: 'GET',
};

function resultHandlerCallback(result) {
var buffer = '';

result.setEncoding('utf8');
result.on('data', function(chunk){
buffer += chunk;
});

result.on('end', function(){
if (callback) {
callback(buffer);
}
});
}

exports.getUserData = function(name, user_callback) {
callback = user_callback
options['path'] = user + '?name=' + name;

var request = https.get(options, resultHandlerCallback);

request.on('error', function(e){
console.log('error from proxy_query:getUserData: ' + e.message)
});

request.end();
}
app.listen(port);

我希望我没有搞砸这段代码,因为我替换了一些东西以适合我的示例。

无论如何,问题是我想在 HTTP 请求完成后将响应发布给用户,但我找不到如何这样做,因为我使用 express,而 express 使用异步调用,http 请求也是如此。我知道如果我想这样做,我应该将响应对象传递给 makeProxyApiRequest,这样他就可以将它传递给回调,但由于异步问题,这是不可能的。

有什么建议吗?帮助将不胜感激。

最佳答案

当您在路由处理中使用您的函数来处理请求时,最好将它们编写为 express 中间件函数,采用特定的请求/响应对,并利用 express 的 next 级联型号:

function makeProxyApiRequest(req, res, next) {
var name = parseProxyApiRequest(req.name);
res.locals.userdata = proxy.getUserData(name);
next();
}

function parseProxyApiRequest(req, res, next) {
try {
// remember that JSON.parse will throw if it fails!
data = JSON.parse(res.locals.userdata);
if (data .error) {
next('An eror has occoured. details: ' + JSON.stringify(data));
}
res.locals.proxyData = data;
next();
}
catch (e) { next("could not parse user data JSON."); }
}

app.post('/api/getuserinfo/tom',
makeProxyApiRequest,
parseProxyApiRequest,
function(req, res) {
// res.write or res.json or res.render or
// something, with this specific request's
// data that we stored in res.locals.proxyData
}
);

更好的做法是现在将这些中间件函数移动到它们自己的文件中,这样您就可以简单地执行以下操作:

var middleware = require("./lib/proxy_middleware");
app.post('/api/getuserinfo/tom',
middleware.makeProxyApiRequest,
middleware.parseProxyApiRequest,
function(req, res) {
// res.write or res.json or res.render or
// something, with this specific request's
// data that we stored in res.locals.proxyData
}
);

并使您的 app.js 尽可能小。请注意,客户端的浏览器将简单地等待 express 的响应,这会发生一次 res.writeres.jsonres.render 等用来。在此之前,浏览器和服务器之间的连接只是保持打开状态,所以如果您的中间件调用需要很长时间,那也没关系 - 浏览器会很乐意地等待很长的时间来返回响应,同时会做其他事情。

现在,为了得到 name,我们可以使用 express 的参数构造:

app.param("name", function(req, res, next, value) {
req.params.name = value;
// do something if we need to here, like verify it's a legal name, etc.
// for instance:
var isvalidname = validator.checkValidName(name);
if(!isvalidname) { return next("Username not valid"); }
next();
});

...

app.post("/api/getuserinfo/:name", ..., ..., ...);

使用此系统,将根据我们使用 app.param 定义的 name 参数处理任何路由的 :name 部分。请注意,我们不需要多次定义它:我们可以执行以下操作,它就会正常工作:

app.post("/api/getuserinfo/:name", ..., ..., ...);
app.post("/register/:name", ..., ..., ... );
app.get("/api/account/:name", ..., ..., ... );

对于每个带有 :name 的路由,“name”参数处理程序的代码将启动。

至于 proxy_query.js 文件,将其重写为适当的模块可能比使用单独的导出更安全:

// let's not do more work than we need: http://npmjs.org/package/request
// is way easier than rolling our own URL fetcher. In Node.js the idea is
// to write as little as possible, relying on npmjs.org to find you all
// the components that you need to glue together. If you're writing more
// than just the glue, you're *probably* doing more than you need to.
var request = require("request");
module.exports = {
getURL: function(name, url, callback) {
request.get(url, function(err, result) {
if(err) return callback(err);
// do whatever processing you need to do to result:
var processedResult = ....
callback(false, processedResult);
});
}
};

然后我们可以将其用作 proxy = require("./lib/proxy_query"); 在中间件中我们需要实际执行 URL 数据获取。

关于javascript - Node.js 响应异步数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27081949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com