在脚本运行完成后允许点击链接

我试图find一种方式,让用户只有在特定的function已经完成运行后点击链接。 所以在我的情况下,我有ejs模板哪里有两个链接parapgraphs。 点击第一个(“运行python”)激活脚本,需要一些时间才能完成。 然后,只有在完成之后(所以“完成” – 来自console.log('finished'打印的行: console.log('finished' )),下一个链接(“查看表格”)将是可点击的(或者是unhid或类似的东西)。

 <h1>Search for a movie</h1> <form action="results" method="GET"> <input type="text" placeholder="search term" name="search"> <input type="submit"> </form> <p><a href="/run"> Run python </a></p> <p><a href="/data"> See the table </a></p> 

这是app.js代码

 var express = require("express") var app = express() var request = require("request") var PythonShell = require('python-shell'); app.set("view engine", "ejs") app.engine('html', require('ejs').renderFile); var thelist =[] app.get("/", function(req, res){ res.render("search") }) var jsondata = "" app.get("/results", function(req, res){ var query = req.query.search var url = "http://www.omdbapi.com/?s=" + query + "&type=series&apikey=thewdb" request(url, function(error, response, body){ if(!error && response.statusCode == 200){ var data = JSON.parse(body) res.render("results", {data: data}) } }) }) app.get('/data', function(req, res) { //viewname can include or omit the filename extension res.render(__dirname + '/well.html'); }); app.get("/show/:id", function (req, res) { var id = req.params.id; thelist.push(id) console.log(thelist); res.redirect('/') }); app.get("/run", function(req, res) { var pyshell = new PythonShell('script2.py'); pyshell.send(JSON.stringify(thelist)) pyshell.on('message', function (message) { // received a message sent from the Python script (a simple "print" statement) jsondata += message }); // end the input stream and allow the process to exit pyshell.end(function (err) { if (err){ throw err; }; console.log('finished'); }); res.redirect('/') thelist = [] }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("Movie App has started!!!"); }) 

你可以用ajax来做,就像emil在他的回答中所说的那样,但是因为你正在使用ejs模板引擎,所以为什么不用它呢?
(您只需将.html模板文件扩展名更改为.ejs )。

另外,我认为你最好的select是不使用res.redirect
最好使用res.render并将一个parameter passing给视图,默认设置为false

一个基本的例子:

server.js

 // ... app.get("/", function (req, res) { res.render("search", { active: false }); }) // ... app.get("/run", function (req, res) { // ... pyshell.end(function (err) { if (err) throw err; console.log('finished'); res.render("search", { active: true }); }); }); 

search.ejs

 <p><a href="/run">Run python</a></p> <p> <%if (active) { %> <a href="/data">See the table</a> <% } else { %> See the table <% } %> </p> 

现在,只有当python脚本完成时,才能点击See the table链接。

概要

这应该通过使用AJAX调用完成。 而不是在/run中使用redirect,你可以让它返回一些表示作业成功/错误状态的JSON数据。

点击Run python ,它将运行AJAX调用,而不是将页面redirect到/

在AJAX调用的OnSuccess上,可以启用查看表格。

HTML

 <p><a id="run" href="/run"> Run python </a></p> <p><a id="show-data" href="/data" style="pointer-events:none;"> See the table </a></p> 

前端Javascript

 $(function() { $('#run').click(function(event) { event.preventDefault(); $.get('/run', function() { $('#show-data').css('pointer-events', 'all'); }); }); }); 

的NodeJS

 app.get("/run", function(req, res) { ... // res.redirect('/'); res.json({ success: true }); }); 

你可以通过使用防止functionjquery来防止链接

  $("a").click(function() { if (status == "1") { return true; } else { return false; e.preventDefault(); } }); 

这是我用来停止用户不运行function导航到其他页面的function。

我初始化一个名为状态值为0的variables

然后,一旦函数成功,我就增加variables。

因此,如果状态为0,那么URL将不起作用,完成该function后,状态将会增加到1,因此如果条件为真,它将返回真正的语句。 如果不是,则会返回false语句,并使用e.preventDefault()

你为什么不尝试socket.io? 这里是简化的代码,但function齐全…

(注意:“msg”对象仅作为示例,供进一步使用)

的index.html

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Title</title> </head> <body> <h1>Search for a movie</h1> <p><a href="#" onclick="runPython()"> Run python </a></p> <p><a id="table-data"> See the table </a></p> <script src="/socket.io/socket.io.js"></script> <script> var msg = { msg: "TestMsgSend", iParam: 100, sParam: "Test Param 1", aParam: [1, 2, 3] } var socket = io(); socket.on("server:finished", function (msg) { // msg = "TestMsgReceived", for further usage console.log("\nId: " + socket.id + "\nmsg: " + msg.msg + "\niParam: " + msg.iParam + "\nsParam: " + msg.sParam + "\naParam: " + msg.aParam); document.getElementById("table-data").setAttribute("href", "/data"); }); function runPython() { socket.emit("client:run", msg); } </script> </body> </html> 

app.js

 var express = require("express"); var app = express(); var http = require("http").Server(app); var io = require("socket.io")(http); app.use("/", express.static(__dirname + "/")); // *************************************************************************** // *************************************************************************** // ***** Your code // *************************************************************************** // *************************************************************************** io.on("connection", function (socket) { console.log("New connection with id: " + socket.id); socket.on("client:run", function (msg) { // msg = "TestMsgSend", for further usage console.log("\nId: " + socket.id + "\nmsg: " + msg.msg + "\niParam: " + msg.iParam + "\nsParam: " + msg.sParam + "\naParam: " + msg.aParam); // *************************************************************************** // *************************************************************************** // ***** Your code // *************************************************************************** // *************************************************************************** msg.msg = "TestMsgReceived"; msg.iParam++; msg.sParam = "Test Param 2"; msg.aParam.push(4, 5, 6) io.emit("server:finished", msg); }); }); // *************************************************************************** // *************************************************************************** // ***** Your code // *************************************************************************** // *************************************************************************** http.listen(80, function () { console.log("listening on *:80"); }); 

的package.json

 { "name": "test", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.16.2", "socket.io": "^2.0.4" } } 

节点app.js开始,享受

为什么不像一个简单的防护variables? 在你的代码中:

 var ready = false; // 1) the guard app.get('/data', function(req, res) { if (ready) { // 2) view execution blocked until guard is ready res.render(__dirname + '/well.html'); } }); app.get("/run", function(req, res) { var pyshell = new PythonShell('script2.py'); pyshell.send(JSON.stringify(thelist)) pyshell.on('message', function (message) { // received a message sent from the Python script (a simple "print" statement) jsondata += message }); // end the input stream and allow the process to exit pyshell.end(function (err) { if (err) { throw err; }; ready = true; // 3) if evetything is OK the guard is now ready console.log('finished'); }); res.redirect('/') thelist = [] });