前端 Sckill.vue
<template>
<div>
<h2>go语言从入门到放弃</h2>
<el-button type="danger" @click="handleSckill">秒杀</el-button>
</div>
</template>
<script>
export default {
name: "Sckill",
data() {
return {
t: null,
task_id: '',
}
},
methods: {
handleSckill() {
this.$axios.post(`${this.$settings.BASE_URL}user/sckill/`, {
name: "性感帽子",
}).then(res => {
if (res.data.code == 100) {
alert('您正在排队')
this.task_id = res.data.task_id
// 起个转圈的东西
// 起定时任务
this.t = setInterval(() => {
this.$axios.get(`${this.$settings.BASE_URL}user/sckill/?task_id=${this.task_id}`).then(res => {
if (res.data.code == 100 || res.data.code == 101) {
this.$message(res.data.msg)
//销毁定时器
clearInterval(this.t)
this.t = null
} else {
console.log('过会再查')
}
})
}, 3000)
}
})
}
}
}
</script>
<style scoped>
</style>
后端
视图类
from celery_task.user_task import sckill_goods
from celery_task.celery import app
from celery.result import AsyncResult
class SckillView(APIView):
def post(self, request, *args, **kwargs):
name = request.data.get('name')
# 提交秒杀异步任务
res = sckill_goods.delay(name)
return APIResponse(task_id=str(res))
def get(self, request, *args, **kwargs):
task_id = request.GET.get('task_id')
a = AsyncResult(id=task_id, app=app)
if a.successful(): # 正常执行完成
result = a.get() # 任务返回的结果
if result:
return APIResponse(code=100, msg='秒杀成功')
else:
return APIResponse(code=101, msg='秒杀失败')
elif a.status == 'STARTED':
print('任务已经开始被执行')
return APIResponse(code=103, msg='还在排队')
else:
return APIResponse(code=102, msg='没成功')
路由
urlpatterns = [
path('sckill/', SckillView.as_view()),
]
任务
@app.task
def sckill_goods(name):
# 逻辑是:开启事务---》扣减库存---》生成订单
import time
time.sleep(6)
res = random.choice([100, 102])
if res == 100:
print('%s被秒杀成功了' % name)
return True
else:
print('%s被秒杀失败了' % name)
return False