Jquery 如何从异步tornado post请求发送响应以在html模板上呈现?
我正在尝试使用tornado的异步功能。到目前为止,我只取得了些许成功。我正在使用我发现的修改版本来帮助我的async。。也许这不是最好的办法,你告诉我你的想法,或者有没有更好的办法。下面是我用来帮助处理异步请求的subprocess_helper.py文件Jquery 如何从异步tornado post请求发送响应以在html模板上呈现?,jquery,python-2.7,asynchronous,response,tornado,Jquery,Python 2.7,Asynchronous,Response,Tornado,我正在尝试使用tornado的异步功能。到目前为止,我只取得了些许成功。我正在使用我发现的修改版本来帮助我的async。。也许这不是最好的办法,你告诉我你的想法,或者有没有更好的办法。下面是我用来帮助处理异步请求的subprocess_helper.py文件 import tornado.process import subprocess import logging from tornado.gen import Task, Return, coroutine from tornado.io
import tornado.process
import subprocess
import logging
from tornado.gen import Task, Return, coroutine
from tornado.ioloop import IOLoop
STREAM = tornado.process.Subprocess.STREAM
@coroutine
def call_subprocess(cmd, stdin_data=None, stdin_async=False):
"""
Wrapper around subprocess call using Tornado's Subprocess class.
"""
stdin = STREAM if stdin_async else subprocess.PIPE
sub_process = tornado.process.Subprocess(
cmd, stdin=stdin, stdout=STREAM, stderr=STREAM
)
if stdin_data:
if stdin_async:
yield Task(sub_process.stdin.write, stdin_data)
else:
sub_process.stdin.write(stdin_data)
if stdin_async or stdin_data:
sub_process.stdin.close()
result, error = yield [
Task(sub_process.stdout.read_until_close),
Task(sub_process.stderr.read_until_close)
]
raise Return((result, error))
def on_timeout():
logging.info("timeout")
#IOLoop.instance().stop()
#IOLoop.instance().stop()
这就是风景
import app.basic
import tornado.web
import time
import os
import shlex
from tornado.ioloop import IOLoop
from tornado.gen import coroutine
#from datetime import datetime
from lib import subprocess_helper
from lib import ad_sizesdb, sitesdb, audit_notesdb
class Repull(app.basic.BaseHandler):
@tornado.web.authenticated
def get(self):
if self.get_secure_cookie("account_type") not in ['admin']:
self.redirect('/')
else:
slug = self.get_argument('slug','')
size = self.get_argument('ad_size', '')
ad_sizes = ad_sizesdb.get_ad_sizes()
slugs = sitesdb.get_all_slugs()
self.render('admin_tools/repull.html', active_section='repull_invocation', ad_sizes=ad_sizes, slug=slug, slugs=slugs, size=size, expand_tools=True)
@tornado.web.authenticated
@coroutine
def post(self):
slug = self.get_argument('slug','')
size = self.get_argument('ad_size', '')
if slug != '' and size != '':
seconds_to_wait = 300
deadline = time.time() + seconds_to_wait
IOLoop.instance().add_timeout(deadline, subprocess_helper.on_timeout)
file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)).replace('app', 'scripts/pull_invocation_codes.py'))
#cmd = shlex.split('python {0} "{1}" "adtech" "{2}"'.format(file_path, slug, size))
cmd = 'ls'
result, error = yield subprocess_helper.call_subprocess(cmd, stdin_async=True)
if result != '':
msg = 'invocation code for {0}_{1} pulled'.format(slug, size)
#log_audit_note(msg)
self.api_response(msg)
else:
msg = 'invocation for {0}_{1} not pull something happened'.format(slug, size)
#log_audit_note(msg)
self.api_response(msg)
else:
self.error(400, 'slug or ad size blank')
#self.redirect('/admin/admin_tools/repull??ad_size={0}&slug={1}'.format(size, slug))
模板
{% set active_section = 'admin_tools' %}
{% extends ../admin.html %}
{% block middle_content %}
<div class="col-sm-6">
<form name="form" action="/admin/admin_tools/repull" method="post">
<div class="form-group">
<label>Ad Size</label>
<select id="ad_size" name="ad_size" data-init-plugin="select2" style="width:100%;">
<option value=""></option>
{% for size in ad_sizes %}
<option value='{{size['size']}}' {% if size['size'] == size %} selected {% end %}>{{size['size']}}</option>
{% end %}
</select>
</div>
<div class="form-group">
<label>Slugs</label>
<select id="slug" name="slug" data-init-plugin="select2" style="width:100%;">
<option value=""></option>
{% for s in slugs %}
<option value='{{s['slug']}}' {% if s['slug'] == slug %} selected {% end %}>{{s['slug']}}</option>
{% end %}
</select>
</div>
<button type="submit" id="submit" class="btn btn-primary">Pull Adtech Invocation Code</button>
</form>
</div>
<div class="col-sm-6">
<div>Notes:</div>
<div id="notes"></div>
</div>
{% end %}
{% block javascript %}
<script>
$(document).ready(function() {
$("form").submit(function(){
$('#notes').html('Running for invocation for ' + slug + '_' + adsize);
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$('#notes').html(data['data']);
return false;
});
return false;
});
});
</script>
{% end %}
{%set active_section='admin_tools%}
{%extends../admin.html%}
{%block middle_content%}
广告尺寸
{对于ad_大小%中的大小为%}
{{size['size']}
{%end%}
鼻涕虫
{%s在slug%中为%s}
{{s['slug']}
{%end%}
拉入Adtech调用代码
笔记:
{%end%}
{%block javascript%}
$(文档).ready(函数(){
$(“表格”)。提交(函数(){
$('#notes').html('为'+slug+'.'+adsize'调用而运行);
$.post($(this.attr(“操作”),$(this.serialize(),函数(数据){
$('#notes').html(data['data']);
返回false;
});
返回false;
});
});
{%end%}
所以有一点背景。我之所以需要此调用是异步的,是因为post请求正在触发另一个文件,该文件使用selenium来帮助实现自动化。有些事情我真的不太明白,也不想得到帮助,包括使用IOLoop.instance().stop()
上面的链接使用它来帮助超时,然后是如何结束post调用。我把它注释掉了,因为如果我不这样做,tornado线程将在文章的末尾终止。考虑到我调用的方法的名称,我认为这是有意义的。。。总的来说,我希望能够运行post-async并在完成后获得某种响应,这样我就可以在模板上触发某种视觉效果,这样用户就可以知道发生了什么/完成了什么/失败了什么。我做错了什么?我怎样才能修好它?如果这不是最好的方法,是什么?提前感谢。更新:我添加了模板,在考虑了它之后,我想我想要的是在模板上正确渲染的响应。我添加了一个我正确得到的图像,它不是我想要的。该消息呈现在空白页面上,但是如果您查看html模板,当我收到响应数据时,我希望jquery将其注入到div中。我在jQuery中返回false,因为我写了多篇文章,所以我必须防止默认
$("form").submit(function(e){
e.preventDefault();
var slug = $('#slug').val();
var adsize = $('#ad_size').val();
if((slug && adsize) != ''){
$('#notes').html('Running for invocation for ' + slug + '_' + adsize + ' if you don\'t want to wait for the reponse you can check the audit notes later');
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$('#notes').html(data['data']);
return false;
});
}
});
因为我写了多篇文章,所以我必须防止违约
$("form").submit(function(e){
e.preventDefault();
var slug = $('#slug').val();
var adsize = $('#ad_size').val();
if((slug && adsize) != ''){
$('#notes').html('Running for invocation for ' + slug + '_' + adsize + ' if you don\'t want to wait for the reponse you can check the audit notes later');
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$('#notes').html(data['data']);
return false;
});
}
});
代码在我看来很不错;你到底在期待什么,现在又发生了什么?您肯定不想在任何地方使用
IOLoop.stop()
;这用于关闭整个服务器,在常规请求中没有位置。您的意思是在帖子中启动子流程,向客户端发送响应,然后在稍后的请求中获得子流程的结果吗?@BenDarnell我在阅读您的评论后对帖子进行了一些更新。添加一些说明,当子流程产生结果时,我希望发送/写入api响应。。它的工作原理是,当我发送数据时,它返回一个带有json响应的空白页面。我希望jQuery接收响应,并将响应注入到div中。谢谢,我了解您现在在寻找什么。不幸的是,我不知道足够的javascript/jquery来帮助您。服务器端很好;这是关于如何从javascript发出请求的问题;你到底在期待什么,现在又发生了什么?您肯定不想在任何地方使用IOLoop.stop()
;这用于关闭整个服务器,在常规请求中没有位置。您的意思是在帖子中启动子流程,向客户端发送响应,然后在稍后的请求中获得子流程的结果吗?@BenDarnell我在阅读您的评论后对帖子进行了一些更新。添加一些说明,当子流程产生结果时,我希望发送/写入api响应。。它的工作原理是,当我发送数据时,它返回一个带有json响应的空白页面。我希望jQuery接收响应,并将响应注入到div中。谢谢,我了解您现在在寻找什么。不幸的是,我不知道足够的javascript/jquery来帮助您。服务器端很好;这是关于如何从javascript发出请求的问题。