You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统一捕获Vue-Concurrency所有Task错误触发弹窗通知?

Vue Concurrency 全局Task错误自动触发Quasar通知实现方案

不需要给每个yield语句单独绑定catch,也不需要依赖不支持链式调用的useTaskGroup,Vue Concurrency本身提供了成熟的事件机制,可以用两种低侵入方案实现全量任务的错误自动提示。

方案1:二次封装useTask组合式函数(最推荐,灵活可控)

对原生useTask做一层轻量封装,统一在封装层监听任务实例的错误事件,自动触发通知。业务代码只需要替换useTask的导入源,原有任务逻辑完全不需要改动。

首先新建封装的组合式函数文件,例如src/composables/useNotifyTask.ts:

import { useTask, type UseTaskOptions, type Task } from 'vue-concurrency';
import { useQuasar } from 'quasar';

export function useNotifyTask<T extends (...args: any[]) => any>(
  generatorFn: T,
  options?: UseTaskOptions
): Task<T> {
  const $q = useQuasar();
  // 调用原生方法创建任务实例
  const task = useTask(generatorFn, options);

  // 监听任务错误事件,抛出错误时自动触发通知
  task.on('error', (err) => {
    // 可在此处扩展自定义逻辑:错误过滤、错误码映射、特殊场景跳转等
    const errorMsg = err instanceof Error ? err.message : '请求异常,请稍后重试';
    $q.notify(errorMsg);
  });

  return task;
}

业务代码中替换导入即可,所有冗余的yield后catch可以全部删除:

<script setup lang="ts">
import { timeout } from 'vue-concurrency';
// 替换原vue-concurrency的useTask导入
import { useNotifyTask } from 'src/composables/useNotifyTask';

const exampleAsyncWithError = async () => {
  await timeout(1);
  throw new Error('Ruh oh! Error.');
};

// 所有任务直接使用封装后的方法创建,错误自动弹窗
const example1Task = useNotifyTask(function* () {
  yield exampleAsyncWithError();
  yield exampleAsyncWithError();
  yield exampleAsyncWithError();
});

const example2Task = useNotifyTask(function* () {
  yield exampleAsyncWithError();
  yield exampleAsyncWithError();
});

const example3Task = useNotifyTask(function* () {
  yield exampleAsyncWithError();
  yield exampleAsyncWithError();
});
</script>

<template>
  <q-btn label="Run Task" @click="example1Task.perform" />
  <q-btn label="Run Task" @click="example2Task.perform" />
  <q-btn label="Run Task" @click="example3Task.perform" />
</template>

该方案的优势:

  • 改造成本极低,仅需替换导入源,存量任务无需修改内部逻辑
  • 灵活度高,可在封装层统一实现错误过滤、格式化、特殊错误分支处理
  • 不侵入任务原有逻辑,任务实例的error、isError等状态正常更新,不影响页面其他错误态展示

方案2:全局插件配置(适合无差异化处理的场景)

如果所有任务的错误提示逻辑完全统一,可以在Vue Concurrency初始化时传入全局任务配置,给所有任务默认绑定错误监听,无需额外封装。
在Quasar的boot启动文件中配置插件:

// src/boot/vue-concurrency.ts
import { boot } from 'quasar/wrappers';
import VueConcurrency from 'vue-concurrency';

export default boot(({ app, $q }) => {
  app.use(VueConcurrency, {
    task: {
      on: {
        error: (err) => {
          const errorMsg = err instanceof Error ? err.message : '请求异常,请稍后重试';
          $q.notify(errorMsg);
        }
      }
    }
  });
});

该方案默认对所有useTask创建的任务生效,如果个别任务不需要弹窗提示,可以在创建任务时单独传入配置覆盖,或在全局错误回调中加标记位过滤特殊错误。

补充:useTaskGroup的错误监听方式

useTaskGroup返回的是任务组实例而非Promise实例,本身不支持then/catch链式调用,但同样可以通过on('error')事件监听组内所有任务的错误,适合临时给一组批量任务绑定提示的场景:

import { useTaskGroup } from 'vue-concurrency';
const taskGroup = useTaskGroup([example1Task, example2Task, example3Task]);
taskGroup.on('error', (err) => {
  $q.notify(err.message);
});

内容的提问来源于stack exchange,提问作者TinyTiger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 13:33:23