node.js - Node/Express 服务器在变量集之前启动
问题描述
我的 node/express 服务器启动时存在问题,因为它在 IP 地址函数/脚本之前加载服务器,该函数/脚本从 EC2 动态检索 hostIp 完成。所以我对后端的调用都在返回undefined
。
示例:(search.js)
const awsHost = require('./host.js');
const hostIp = awsHost.getBackendHost();
const host = `http://${ hostIp }:1234`;
console.log(host);
console.log(hostIp);
console.log(awsHost.getBackendHost());
输出:
[nodemon] restarting due to changes...
[nodemon] starting `node src/index.js`
http://undefined:1234
undefined
Server: Success -port 1111
11.123.456.789
这是我的(index.js)的当前状态:
const express = require('express');
const app = express();
app.use(express.static('./web/'));
app.listen(1111, () => console.info('Server: Success -port 1111'));
require('./routes/routes.js')(app);
module.exports = app;
如何强制 NodeawsHost.getBackendHost()
在最终服务器启动之前运行该功能并加载它?
编辑(host.js):
const aws = require('aws-sdk');
aws.config.update({ region: 'REGION' });
const getBackendHost = () => {
const ecs = new aws.ECS();
const ec2 = new aws.EC2();
const backendPort = '1234';
const clusterParameters = {
cluster: 'CLUSTER',
};
ecs.listContainerInstances(clusterParameters, (listContainerError, listContainerData) => {
if (listContainerError) console.log(listContainerError, listContainerError.stack);
else {
const containerInstanceParameters = {
cluster: clusterParameters.cluster,
containerInstances: listContainerData.containerInstanceArns
};
ecs.describeContainerInstances(containerInstanceParameters, (describeContainerError, describeContainerData) => {
if (describeContainerError) console.log(describeContainerError, describeContainerError.stack);
else {
describeContainerData.containerInstances.forEach((container) => {
container.remainingResources.forEach((dataSet) => {
if (dataSet.stringSetValue && dataSet.stringSetValue.includes(backendPort)) {
const containerInstanceId = {
InstanceIds: [
container.ec2InstanceId
]
};
ec2.describeInstances(containerInstanceId, (describeInstanceError, describeInstanceData) => {
if (describeInstanceError) console.log(describeInstanceError, describeInstanceError.stack);
else {
const iP = describeInstanceData.Reservations[0].Instances[0].PrivateIpAddress;
console.log(iP);
return iP;
}
return describeInstanceError;
});
}
});
});
}
});
}
});
};
module.exports = {
getBackendHost
};
解决方案
您实际上需要遵循 API 建议的回调约定。节点 AWS API 使用节点样式错误优先回调来执行异步调用。您需要等待这些呼叫完成。
更改您getBackendHost()
的接受回调:function(err, host){...}
或承诺它。然后在您的应用程序中,等待调用完成并使用回调正确设置主机。
此外,嵌套forEach
部分也需要在考虑到异步性的情况下重写。
它将类似于:
// host.js
const aws = require("aws-sdk");
aws.config.update({
region: "REGION"
});
/*
* Expect a node style callback of the signature:
* function(err, ip){...}
*/
function getBackendHost(cb) {
const ecs = new aws.ECS();
const ec2 = new aws.EC2();
const backendPort = "1234";
const clusterParameters = {
cluster: "CLUSTER"
};
ecs.listContainerInstances(clusterParameters, (listContainerError, listContainerData) => {
// Bail from error
if (listContainerError) return cb(listContainerError, null);
const containerInstanceParameters = {
cluster: clusterParameters.cluster,
containerInstances: listContainerData.containerInstanceArns
};
ecs.describeContainerInstances(containerInstanceParameters, (describeContainerError, describeContainerData) => {
// Bail from error
if (describeContainerError) return cb(describeContainerError, null);
/*
* You will also need to rewrite this because you are iterating over async items and still not waiting for them
*/
describeContainerData.containerInstances.forEach(container => {
container.remainingResources.forEach(dataSet => {
if (dataSet.stringSetValue && dataSet.stringSetValue.includes(backendPort)) {
const containerInstanceId = {
InstanceIds: [
container.ec2InstanceId
]
};
ec2.describeInstances(containerInstanceId, (describeInstanceError, describeInstanceData) => {
// Bail from error
if (describeInstanceError) return cb(describeInstanceError, null);
return cb(null, describeInstanceData.Reservations[0].Instances[0].PrivateIpAddress);
});
}
});
});
});
});
}
module.exports = {
getBackendHost
};
// index.js
const awsHost = require('./host.js');
const hostIp = awsHost.getBackendHost(function(err, hostIp) {
// Bail from error
if (err) return console.error(err);
const host = `http://${ hostIp }:1234`;
console.log(host);
console.log(hostIp);
console.log(awsHost.getBackendHost());
});
推荐阅读
- java - 从对象中获取非空值
- linux - 在每个部分的标题中按 (DOW MON DD YY) 日期对分成多个部分的文件进行排序
- python-3.x - 使用来自另一个列表的值在 Tkinter 中定义标签
- java - 在 Java 应用程序中使用 Python 微服务
- numpy - 使用 numpy 对 pandas 数据框进行多项式拟合
- r - R:在给定其他值的情况下,我如何找到 beta 函数的参数?
- python - 使用字符串变量来控制文本框属性
- javascript - ReactJS:尝试使用表单登录后呈现新屏幕,从 Express JSON 获取数据
- javascript - 设置 HTML 框架 src 在 Safari 中不起作用
- ios - 当mapview是属性时如何使用点击标记事件