对于一些耗时的任务,我们希望能够后台执行,同时能够知道任务的执行情况,本文是用celery做的一个小任务,希望对你有所启发。
celery 是python写的包所以我们可以
pip install celery
任务的状态默认有:
PENDING:任务尚未执行(可能在排队等待)
SUCCESS:任务执行成功
FAILURE:任务执行失败
当然我们自己也可以定义状态,比如:PROGRESS :任务正在执行
异步获取任务状态和信息
@app.route('/get/state/<int:task_id>', methods=['GET'])
def get_celery_state(task_id):
task = test_task.AsyncResult(task_id)
if task.info:
response['percent'] = task.info.get('percent', 0)
else:
response['percent'] = 0
reponse_map = {
'FAILURE': u'任务执行失败...',
'PENDING': u'任务执行正在开始...',
'PROGRESS': u'任务正在执行...',
'SUCCESS': u'任务执行结束...'
}
response['message'] = reponse_map[task.state]
return jsonify({'data':{'response':response}),200
任务函数
@celery.task(bind=True)
def test_task(self):
import time
while i <100 :
i+=1
time.sleep(1)
self.update_state(state='PROGRESS', meta={'percent': i})
return {'percent':100}
开始任务
@app.route('/test/celery', methods=['POST'])
def test_celery():
task = test_task.apply_async()
resp = {'data': {'task_id':task.id,'status':0}}
return jsonify(resp), 200
前端html代码
<div class="progress progress-striped" style="display: none">
<div class="progress-bar progress-bar-success" role="progressbar"
aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
style="width: 0%;">
<span>0%</span>
</div>
</div>
js代码:
function get_task_info(task_id, process_div, progress_bar) {
$.get('/get/status/' + task_id, function (e) {
var percent = e.data.reponse['percent'];
progress_bar.css({'width': percent + '%'});
process_div.find('span').text(percent + '%');
if (e.data.reponse['state'] == 'SUCCESS') {
progress_bar.css({'width': 0 + '%'});
process_div.find('span').text(0 + '%');
process_div.hide();
return 1
} else {
setTimeout(function () {
get_task_info(task_id, process_div, progress_bar)
}, 1000)
}
})
}
function check_item_data() {
var process = $('.progress');
var progress_bar = $('.progress-bar');
process.show();
$.ajax({
url: "/test/celery",
method: "post",
success: function (e) {
if (e.data.status == 0) {
get_task_info(e.data.task_id, process, progress_bar);
} else {
alert("商品数据导入失败");
}
},
error: function () {
alert("商品数据导入失败");
}
})
}
效果图