我正在开发一个节点js应用程序。在我的应用程序中,我从节点js app调用脚本文件。
在该脚本文件中,我正在用azure创建一个HDI集群。
我想显示一个微调器,直到脚本完成HDI集群的创建,并在脚本执行后隐藏微调器。
如何使用Node js应用程序显示?给我举个例子?
index.js
<div class="container">
<fieldset>
<form action="/" method="post">
<h4>Create Cluster</h4><br><br>
<label for="name"> Name: </label>
<input name="name" type="text" class="name" placeholder="Enter a name" required><br><br>
<input type="submit" class="button" value="Create">
</form>
</fieldset>
<div id="load"></div>
</div>
server.js
app.post('/', function (req, res) {
res.render('index');
var child = exec('bash sample.sh');
child.stdout.on('data', function(data) {
logger.info(data)
});
child.stderr.on('data', function(data) {
logger.error(data);
});
child.on('close', function(code) {
logger.info('Script exit code: ' + code);
});
})
sample.sh
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# -e: immediately exit if any command has a non-zero exit status
# -o: prevents errors in a pipeline from being masked
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
declare subscriptionId=""
declare resourceGroupName=""
declare deploymentName=""
declare resourceGroupLocation=""
# Initialize parameters specified from command line
while getopts ":i:g:n:l:" arg; do
case "${arg}" in
i)
subscriptionId=${OPTARG}
;;
g)
resourceGroupName=${OPTARG}
;;
n)
deploymentName=${OPTARG}
;;
l)
resourceGroupLocation=${OPTARG}
;;
h)
echo "This message"
esac
done
shift $((OPTIND-1))
#Prompt for parameters is some required parameters are missing
if [[ -z "$subscriptionId" ]]; then
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
echo "Enter your subscription ID:"
read subscriptionId
[[ "${subscriptionId:?}" ]]
fi
if [[ -z "$resourceGroupName" ]]; then
echo "This script will look for an existing resource group, otherwise a new one will be created "
echo "You can create new resource groups with the CLI using: az group create "
echo "Enter a resource group name"
read resourceGroupName
[[ "${resourceGroupName:?}" ]]
fi
if [[ -z "$deploymentName" ]]; then
echo "Enter a name for this deployment:"
read deploymentName
fi
if [[ -z "$resourceGroupLocation" ]]; then
echo "If creating a *new* resource group, you need to set a location "
echo "You can lookup locations with the CLI using: az account list-locations "
echo "Enter resource group location:"
read resourceGroupLocation
fi
#templateFile Path - template file to be used
templateFilePath="template.json"
if [ ! -f "$templateFilePath" ]; then
echo "$templateFilePath not found"
exit 1
fi
#parameter file path
parametersFilePath="parameters.json"
if [ ! -f "$parametersFilePath" ]; then
echo "$parametersFilePath not found"
exit 1
fi
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
usage
fi
#login to azure using your credentials
az account show 1> /dev/null
if [ $? != 0 ];
then
az login
fi
#set the default subscription id
az account set --subscription $subscriptionId
set +e
#Check for existing RG
az group show $resourceGroupName 1> /dev/null
if [ $? != 0 ]; then
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
set -e
(
set -x
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
)
else
echo "Using existing resource group..."
fi
#Start deployment
echo "Starting deployment..."
(
set -x
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
)
if [ $? == 0 ];
then
echo "Template has been successfully deployed"
fi
答案 0 :(得分:1)
您尝试实现的内容类似于将在服务器端运行的长异步处理任务。此过程将由您的用户或前端代码启动。
有几种方法可以根据完成任务所需的平均预期时间来处理此类方案。让我们将它们区分为:
<强> 1。操作时间少于3秒(&lt; = 3000ms)
在这种情况下,您可以了解操作所需的时间,例如读取文件或创建群集或设置mongo数据库等等。因此,您可以从前面进行简单的XHR或AJAX调用。结束代码到节点服务器。
//index.html
<fieldset>
<form action="javascript:void(0);" onSubmit="makeRequest()" method="post">
<h4>Create Cluster</h4><br><br>
<label for="name"> Name: </label>
<input name="name" type="text" class="name" placeholder="Enter a name" required><br><br>
<input type="submit" class="button" value="Create" onclick="makeRequest()">
</form>
</fieldset>
<div id="myLoader"></div>
</div>
<script>
// I have missed some code for sake of breviety
var makeRequest = function() {
//get the value entered by the user in name input box
var data = {name: 'xyz'};
data.name = document.getElementsByName('name').value;
//Since your request is about to begin
//after user has clicked on action button
//Show loader
document.getElementById("myLoader").style.opacity = 1;
//Loader is visible to user
var xhr = new XMLHttpRequest();
...
xhr.addEventListener("readystatechange", function() {
if (this.readyState === 4) {
//Since your request is complete
//Hide loader
document.getElementById("myLoader").style.opacity = 0;
console.log(this.responseText);
}
});
xhr.open("POST", "http://mynodeserver/api/perfromOperation");
xhr.setRequestHeader("content-type", "application/json");
xhr.send(inputDataForserver);
}
</script>
另一方面,服务器端将处理来自操作的请求,并在不超过3秒的时间内返回响应。
//Server.js
//This will load our index.html on users browser
app.post('/', function(req, res) {
res.render('index');
});
//OR
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
//This endpoint will be called by user action
app.post('/api/perfromOperation', function(req, res) {
//The data sent from UI is found in req.body
//Make sure the data path is as needed...
var name = req.body.name;
var child = exec('bash sample.sh -n '+name);
...
...
child.on('close', function(code) {
logger.info('Script exit code: ' + code);
res.json({ "code": code });
});
});
<强> 2。操作时间超过3秒(=> 3000ms)
这种情况将要求您拥有更复杂的流程,您可以从前端调用服务器,这将触发创建Azure群集的漫长过程。
这将在临时数据库中创建一个关于操作的记录,其中包括 - [operationId:#1] [状态:&#39; In_Progress&#39;] 然后,在ID#1的操作完成或出错后,您将更新此记录。
同样,这将要求您从前端拨打另一个电话来检查状态。
* note :时间用作参考,可能会根据您自己的规格和偏好而有所不同。
我希望这会有所帮助,如果您想在页面加载时触发群集创建操作,您也可以通过在文档onLoad事件上进行前面提到的XHR调用来实现。