🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Job计划任务功能开发 计划任务包括两种应用模式: 精确延时任务 、轮询计划任务 ## **精确延时任务** 精确延时任务一般是在某个具体的时间点,触发任务。比如有这样的需求,拼团活动创建,30分钟内,要不成团,要不关闭。整点秒杀活动在13:35:00这个时间正点开始。这样的需求,使用精确延时任务可以实现相关功能。 ***** 插件开发中精确延时任务的开发步骤 1. 精确延时任务的使用简单,您可以在任意需要调用精确延时的地方启动任务计划,调用方法如下 ``` OrderClose::dispatch([, secs:20) ; ``` 通过上面的方法调用,就启动了一个20秒后,会自动执行回调的精确延时任务 OrderClose是继承自BaseJob的一个子类,BaseJob是继承自Dispatch的一个子类,dispatch是一个静态方法,用于调用精确延时任务的方法。 dispatch的第一个参数是 action, 表示一个方法名,默认不填,就是 doJob方法回调,也可以传入自己定义的回调函数方法名称 ,第二个参数secs 表示延时的秒数,如果是更长时间,某年某月某日后的某个时间点,自己计算赋值 ``` class Dispatch { /** * 加入队列 * @param $action * @param array $data * @param string|null $queue_name * @return mixed */ public static function dispatch($action, array $data = [], int $secs = 0, string $queue_name = null, bool $is_async = true) { $class = get_called_class();//调用主调类 if ($is_async) { $queue = Queue::instance()->job($class)->secs($secs); if (is_array($action)) { $queue->data(...$action); } else if (is_string($action)) { $queue->method($action)->data(...$data); } if ($queue_name) { $queue->setQueueName($queue_name); } return $queue->push(); } else { $class_name = '\\' . $class; $res = new $class_name(); if (is_array($action)) { return $res->doJob(...$action); } else { return $res->$action(...$data); } } } } ``` 2. 计划任务的精确时间延时点到达后,系统自动回调,然后在OrderClose类中相应的doJob函数中,编写具体的业务逻辑实现代码 ``` /* * 队列异步调用定时任务 */ class OrderClose extends BaseJob { public function doJob() { Log::write('订单关闭计划任务'.date('Y-m-d h:i:s')); return true; } } ``` ![](https://img.kancloud.cn/14/d6/14d60700907f9ae5dbba5c1d1b1f94b7_1407x780.png) <br> <br> <br> ## **轮询计划任务** 轮询计划任务是按照固定的时间间隔触发,在每个触发的时间间隔,开发者在对应的回调函数(异步函数)中,对相关的业务逻辑进行处理,通常时间间隔可以设置为1分钟。例如有这样的应用场景,检测站点是否到期,程序处理自动关闭操作。又如订单创建后,30分钟内没有人付款,订单自动关闭。一般这样的业务逻辑,对时间的要求不是非常精准的。就可以在轮询中进行处理。 ***** 插件开发中轮训计划任务的开发步骤 1. 在插件的目录`addon\hello_world\app\dict\schedule.php` 文件中, 编写轮训计划任务的相关数据描述定义 ``` return [ [ 'key' => 'order_close', 'name' => '未支付订单自动关闭', 'time' => [ 'type' => 'min', ], 'class' => '', 'function' => '' ] ]; ``` `'key' => 'order_close'` order_close 对应 OrderClose两个单词,目前在niucloud-admin框架内部系统加载的时候,如果没有填写class 参数,会自动寻找 `app\job\schedule`目录下对应的文件名来装载类 ` 'name' => '未支付订单自动关闭'` 计划任务的名称 `'time' => [ 'type' => 'min', ]` 计划任务的执行时间,一般写min 表示每分钟间隔会调用 class 下的 function 函数一次 ` 'class' => ''` 这个表示任务时间间隔时,回调的处理类,要带命名空间,对于插件开发,这里必须填写完整的类路径 如 addon\hello_world\app\job\schedule\OrderClose ( 对于插件中开发计划任务,目前框架没有优化处理自动找寻类, ),注意!这里的schedule目录不是固定的,可以定义任意路径 ` 'function' => '' ` 计划任务回调执行的函数,默认为空,则函数为 doJob 。 开发人员可以定义人员的函数名称 ![](https://img.kancloud.cn/47/20/47209c434e71d3abe4673d3ce679370e_1258x800.png) <br> 2. 计划任务时间触发,自动回调,在相应的函数中,编写具体的业务逻辑实现代码 ``` /* * 队列异步调用定时任务 */ class OrderClose extends BaseJob { public function doJob() { Log::write('订单关闭计划任务'.date('Y-m-d h:i:s')); return true; } } ``` ![](https://img.kancloud.cn/14/d6/14d60700907f9ae5dbba5c1d1b1f94b7_1407x780.png) <br>