一、逻辑分析

第一步:在项目根目录新建包

image

第二步:在使用提交异步任务的位置,导入使用即可

视图函数中使用,导入任务
任务.delay() # 提交任务

第三步:启动worker,如果有定时任务,启动beat

# 启动worker
celery -A celery_task worker -l info -P eventlet
# 启动beat
celery -A celery_task beat -l info

第四步:等待任务被worker执行

执行完任务之后查看任务执行的结果

二、秒杀案例

一、秒杀案例的逻辑分析:

第一:在前端用户按“秒杀”按钮
第二:就发送axios请求到后端
第三:路由匹配成功就会执行相对应的视图函数
第四:提价秒杀任务(这时借助于celery提交到任务中间件了)
第五:第一次的秒杀请求就回去了 携带者任务id在前端
第六:前端开启定时任务,每个三秒钟带着任务向后端发送请求查看是否秒杀成功
第七:在后端任务还在等待被执行返回给前端
第八:如果执行结果是秒杀成功就返回【恭喜秒杀成功】
第九:如果执行结果是秒杀失败就返回【秒杀失败】

二、具体代码实践演示

视图层代码

from celery_task.celery import app
from celery.result import AsyncResult
from celery_task.order_task import seckill_task
from rest_framework.viewsets import ViewSet
from common_response import APIResponse
from rest_framework.decorators import action


class SeckillView(ViewSet):
    @action(methods=['GET'], detail=False)
    def seckill(self, request):
        a = request.query_params.get('id')
        # 使用异步 提交一个秒杀任务
        res = seckill_task.delay(a)
        return APIResponse(task_id=res.id)


    def get_result(self,request):
        task_id = request.query_params.get('task_id')
        a = AsyncResult(id=task_id,app=app)
        if a.successful():
            result = a.get()
            if result:
                return APIResponse(msg='秒杀成功')
            else:
                return APIResponse(code=101, msg='秒杀失败')
        elif a.status == 'PENDING':
            print('任务等待中被执行')
            return APIResponse(code=666,msg='还在秒杀中')

路由层代码

from rest_framework.routers import SimpleRouter
from . import views

router = SimpleRouter()
# http://127.0.0.1:8000/api/v1/user/seckill/seckill
router.register('seckill', views.SeckillView, 'seckill')
urlpatterns = [
]
urlpatterns += router.urls

前端代码

<template>
  <div>

    <button @click="handleSeckill">秒杀</button>
  </div>
</template>

<script>
import Header from '@/components/Header';
import Banner from '@/components/Banner';
import Footer from '@/components/Footer';

export default {
  name: 'Seckill',
  data() {
    return {
      task_id: '',
      t: null
    }
  },
  methods: {
    handleSeckill() {
      this.$axios.get(this.$settings.BASE_URL + '/user/seckill/seckill/?id=1').then(res => {
        this.task_id = res.data.task_id
        this.t = setInterval(() => {
          this.$axios.get(this.$settings.BASE_URL + '/user/seckill/get_result/?task_id=' + this.task_id).then(res => {
            if (res.data.code == 666) {
              //如果秒杀任务还没执行,定时任务继续执行
              console.log(res.data.msg)
            } else {
              // 秒杀结束,无论成功失败,这个定时任务都结束
              clearInterval(this.t)
              this.t = null
              this.$message(res.data.msg)
            }

          })
        }, 2000)
      }).catch(res => {

      })
    }
  }

}
</script>