vue做任务工具方法的实现

需求:须有普通任务(在其他页面完成指定操作,如点赞、转发等后提示完成)和浏览任务指定浏览秒数。

实现:因全局有多处时候封装成一个工具方法,且一次只能进行一个任务,设置一个开始任务类型,完成操作的时候判断改类型任务是否进行中,如果是则调用完成方法;浏览任务为设置当前任务待开始,进入指定浏览页面后判断当前待开始的任务是否数据当前浏览任务,是则开始倒计时,中途离开则中断倒计时,倒计时完成则自动调用完成方方达。当前任务进行中点击了别的任务开始则进行类型覆盖

js 复制代码
// src/stores/taskStore.ts
import { defineStore } from 'pinia';

interface TaskConfig {
    type: LifeTaskType;
    duration?: number; // 倒计时持续时间(毫秒)
    onCompleted?: () => void;
    onInterrupted?: () => void;
}

interface RunningTask extends TaskConfig {
    startTime: number;
    timerId?: number;
}

interface TaskState {
    runningTask: RunningTask | null; // 只允许一个任务运行
    pendingTask: RunningTask | null; // 待开始的任务
}

export enum LifeTaskType {
    Browse = 'browse',//浏览
    Share = 'share',//分享
    Comment = 'comment',//评论
    Publish = 'publish',//发布
    Like = 'like',//点赞
}

export const useTaskStore = defineStore('task', {
    state: (): TaskState => ({
        runningTask: null,
        pendingTask: null // 待开始的任务
    }),

    getters: {
        // 检查指定任务类型是否正在运行
        isTaskRunning: (state) => (taskType: string): boolean => {
            return state.runningTask !== null && state.runningTask.type === taskType;
        },

        // 获取当前运行的任务类型
        getCurrentTaskType: (state) => (): string | null => {
            return state.runningTask ? state.runningTask.type : null;
        },

        // 获取剩余时间
        getRemainingTime: (state) => (): number | null => {
            const task = state.runningTask;
            if (!task || !task.duration) {
                return null;
            }

            const elapsed = Date.now() - task.startTime;
            return Math.max(0, task.duration * 1000 - elapsed);
        },
    },

    actions: {
        /**
          * 开始一个任务,会停止之前运行的任务
       */
        startTask(config: TaskConfig): boolean {
            // 先停止当前运行的任务
            if (this.runningTask) {
                this.interruptCurrentTask(true);
            }

            const task: RunningTask = {
                ...config,
                startTime: Date.now(),
            };

            // 对于需要倒计时的浏览任务,先放入待开始队列
            if (config.duration) {
                // 设置为待开始状态,等待用户确认开始后才启动倒计时
                this.pendingTask = task;
                return true;
            }

            // 非浏览任务直接开始
            this.runningTask = task;
            return true;
        },



        //启动待开始的任务(开始倒计时)
        startPendingTask(): boolean {
            if (!this.pendingTask) {
                console.warn('No pending task to start');
                return false;
            }

            const task = this.pendingTask;

            // 创建倒计时
            if (task.duration) {
                const timerId = setTimeout(() => {
                    this.completeTask();
                }, task.duration * 1000);

                task.timerId = timerId as unknown as number;
            }
            console.log('开始任务', task.type)
            // 将待开始任务转为运行中任务
            this.runningTask = task;
            this.pendingTask = null;

            return true;
        },
        //获取待开始的任务
        getPendingTaskType(): LifeTaskType | null {
            return this.pendingTask?.type || null;
        },

        /**
         * 完成当前任务
         */
        async completeTask() {
            const task = this.runningTask;
            if (!task) {
                console.warn('No task is currently running');
                return false;
            }

            try {
            //这里调用完成方法
                    uni.showToast({
                        title: '恭喜你,任务完成',
                        icon: 'success',
                        duration: 3000,
                    });

                // 清理定时器
                if (task.timerId) {
                    clearTimeout(task.timerId);
                }

                // 执行完成回调
                task.onCompleted?.();
                this.pendingTask = null;
                this.runningTask = null;
            } catch (error) {
                console.error('Failed to complete task:', error);
            }
        },

        /**
         * 中断当前任务
         */
        interruptCurrentTask(isNewTask = false): boolean {
            const task = this.runningTask;
            if (!task) {
                console.warn('No task is currently running');
                return false;
            }
            console.log('中断任务', task.type)
            // 清理定时器
            if (task.timerId) {
                clearTimeout(task.timerId);
            }
            //如果不是浏览任务或新任务,清除待开始任务,保留浏览类型的浏览任务
            if (!(task.type === LifeTaskType.Browse ||  isNewTask) {
                task.onInterrupted?.();
                this.pendingTask = null;
                this.runningTask = null;
            }
            // 执行中断回调

            return true;
        },

        /**
         * 清除当前任务
         */
        clearCurrentTask() {
            const task = this.runningTask;
            if (task) {
                if (task.timerId) {
                    clearTimeout(task.timerId);
                }
                task.onInterrupted?.();
                this.pendingTask = null;
                this.runningTask = null;
            }
        }
    }
});

这里是调用:

js 复制代码
//开始浏览任务
 startTask({ type: 'browse', duration: 60 })

//开始普通任务
 startTask({ type: 'like' })


//判断当前页面进行中的任务,并在完成操作后调用
 if (isTaskRunning('like')) {
     completeTask()
   }
相关推荐
We་ct15 分钟前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
TON_G-T29 分钟前
day.js和 Moment.js
开发语言·javascript·ecmascript
IT_陈寒35 分钟前
JavaScript开发者必看:5个让你的代码性能翻倍的隐藏技巧
前端·人工智能·后端
Irene199141 分钟前
JavaScript 中 this 指向总结和箭头函数的作用域说明(附:call / apply / bind 对比总结)
javascript·this·箭头函数
2501_921930831 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-appearance(更推荐自带的Appearance)
javascript·react native·react.js
还是大剑师兰特1 小时前
Vue3 中 computed(计算属性)完整使用指南
前端·javascript·vue.js
井川不擦1 小时前
前端安全通信方案:RSA + AES 混合加密
前端
孜孜不倦不忘初心1 小时前
Ant Design Vue 表格组件空数据统一处理 踩坑
前端·vue.js·ant design
AD_wjk1 小时前
Android13系统集成方案
前端
Joyee6911 小时前
RN 的新通信模型 JSI
前端·react native