gpt4 book ai didi

javascript - Node.js 的 REST API 无法同时向自身发出请求

转载 作者:行者123 更新时间:2023-11-28 20:26:20 25 4
gpt4 key购买 nike

我使用 node.js 制作了一个 REST API 服务,它工作得很好,直到我在浏览器中打开几个选项卡并(几乎)同时发出几个请求。发送请求的最后一个选项卡获得响应,而另一个选项卡则挂起。

基本上我有一个名为“service”的模块,它可以完成所有工作:

var service = require('./service');
var server = http.createServer(function(req, res) {
...
var serviceResult = service.runService(parsedURL.query.username, parsedURL.query.api_key);

res.writeHead(200, {'content-type': 'application/json', 'connection' : 'keep-alive' });

service.ready = function(serviceResult) {
var serviceResultJSON = JSON.stringify(serviceResult);
res.writeHead(200, {'content-type': 'application/json', 'connection' : 'close' });
res.end(serviceResultJSON);
}

}

从我调用的服务模块中:

service.ready(result);

...只要结果准备好,简而言之,这就是我的服务器。那么我该如何解决这个问题呢?

编辑:

这是我的 service.js 模块的样子(在建议的更改之后):

// PUBLIC

exports.runService = function(username, apiKey, callback) {
_.username = username;
_.apiKey = apiKey;
init();

userManager.setLastServiceGlobal(function() {
// This call triggers the whole cycle. Below is snapshotManager.createdSnapshot(), which gets executed from within snapshotManager and the cycle moves on until apiManager.ready() gets called from within api-manager.js
snapshotManager.createSnapshot(false);
});

// This is the last .ready() function that gets executed when all other modules have finished their job.

apiManager.ready = function() {
console.log('API Manager ready.');
userManager.updateLastService();
callback(null, serviceResult);
}
}

// PRIVATE

var userManager = require('./user-manager'),
productManager = require('./product-manager'),
commentsManager = require('./comments-manager'),
apiManager = require('./api-manager'),
milestonesManager = require('./milestones-manager'),
statisticsManager = require('./statistics-manager'),
snapshotManager = require('./snapshot-manager'),
serviceResult;

...

snapshotManager.createdSnapshot = function() {
userManager.refreshUserData();
}
snapshotManager.createdNewSnapshot = function() {
milestonesManager.generateMilestones();
}
userManager.refreshedUserData = function() {
userManager.isTimeForPortfolioParse();
}

...

userManager.ready = function() {
console.log('User Manager ready.');
userManagerReady = true;
isDataFetchingOver();
}
productManager.ready = function() {
console.log('Product Manager ready.');
productManagerReady = true;
isDataFetchingOver();
}
commentsManager.ready = function() {
console.log('Comments Manager ready.');
commentsManagerReady = true;
isDataFetchingOver();
}

在这种情况下,模块会被覆盖,就像“server.js”文件中的“service”模块一样,对吗?我猜我需要到处实现回调而不是 .ready() 函数,对吗?

最佳答案

这里存在三个问题!

  1. 您正在为 service 设置 ready 属性,而只有一个 service 对象。如果两个请求发生的时间非常接近,您最终可能会在第一个请求被触发之前用第二个请求覆盖 ​​ready 属性。这是因为 service 对象只有一个实例。这几乎肯定是应该的方式,所以不用担心,但我们必须找到一种新的方法来向您的使用代码发出服务操作已完成的信号。
  2. 您在 service.read 中的 res 变量可能与您认为的 res 不同。第二次被调用时,情况会有所不同。这是因为您正在重新定义 ready 属性,因此它每次都会获得不同的范围。
  3. 您发送了两次 header 。这是一个简单的修复方法 - 只是在您知道它们应该是什么之前不要发送任何 header 。这将在下面变得显而易见。

要解决第一个问题,我建议您使用回调!您应该已经从 Node 核心开始熟悉它们,它们几乎用于所有用途。这也恰好解决了第二个问题,凭借 scope在 JavaScript 中。

注意:我建议使用回调而不是工厂或其他方法的原因是回调在 Node 领域很普遍,所以如果你使用它们,你很有可能会与其他库等集成更容易。

以下是我如何执行您的服务器代码:

var service = require('./service');
var server = http.createServer(function(req, res) {
// note that we're not immediately sending headers anymore - this
// fixes the third problem with what you had before

service.runService(parsedURL.query.username, parsedURL.query.api_key, function(err, serviceResult) {
// check for errors! tell the client!
if (err) {
res.writeHead(500);
res.end();
return;
}

res.writeHead(200, {
'content-type': 'application/json',
'connection' : 'keep-alive',
});

var serviceResultJSON = JSON.stringify(serviceResult);

res.end(serviceResultJSON);
});
};

这是我实现 service 的方式:

var service = module.exports = {};

service.runService = function runService(username, key, cb) {
// assume `database` exists from somewhere else...
database.getUser(username, function(err, user) {
// make sure we send any errors up the line
if (err) {
cb(err);
return;
}

// here's an error we've decided on
if (user.key !== key) {
cb(Error("key is incorrect!"));
return;
}

// this is a very common usage pattern - cb(error, result, ...)
// the reason we're calling this will `null` for the error is a bit
// of a double negative - we're saying "there was no error".
cb(null, user);
});
};

关于javascript - Node.js 的 REST API 无法同时向自身发出请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17328726/

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