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

如何让ember-concurrency Ajax限流示例在开发环境正常运行?

修复方案

1. 修正任务定义语法

Ember 4.x + ember-concurrency 2.x中,@task装饰器不能直接赋值生成器函数,需改用task()函数创建任务并绑定组件上下文,确保任务能正确执行并访问组件实例的方法/属性。

2. 启用日志数组的响应式更新

Glimmer组件中普通数组不是响应式的,需用@tracked装饰器标记logs,同时修改log方法的数组更新逻辑,确保模板能感知到数组变化。

3. 调整enqueueTask的参数顺序

ember-concurrency 2.x中enqueueTask的正确参数顺序是先传任务函数,再传选项对象,原代码的参数顺序错误导致任务无法正常触发。


修改后的完整组件JS代码
import Component from '@glimmer/component';
import { enqueueTask, task, timeout } from 'ember-concurrency';
import { tracked } from '@glimmer/tracking';

function loopingAjaxTask(id, color) {
  console.log('looping Ajax task outer function');
  return function* () {
    console.log('looping Ajax task inner function');
    while (true) {
      this.log(color, `Task ${id}: making AJAX request`);
      yield this.ajaxTask.perform();
      this.log(color, `Task ${id}: Done, sleeping.`);
      yield timeout(2000);
    }
  };
}

export default class AjaxThrottlingComponent extends Component {
  tagName = '';
  // 标记为响应式数组
  @tracked logs = [];

  // 调整enqueueTask参数顺序
  ajaxTask = enqueueTask(async () => {
    console.log('inside the task');
    await timeout(2000 + 2000 * Math.random());
    return {};
  }, { maxConcurrency: 3 });

  // 用task()函数创建任务,绑定上下文并设置初始化时自动执行
  task0 = task(loopingAjaxTask(0, '#0000FF').bind(this), { on: 'init' });
  task1 = task(loopingAjaxTask(1, '#8A2BE2').bind(this), { on: 'init' });
  task2 = task(loopingAjaxTask(2, '#A52A2A').bind(this), { on: 'init' });
  task3 = task(loopingAjaxTask(3, '#DC143C').bind(this), { on: 'init' });
  task4 = task(loopingAjaxTask(4, '#20B2AA').bind(this), { on: 'init' });
  task5 = task(loopingAjaxTask(5, '#FF1493').bind(this), { on: 'init' });
  task6 = task(loopingAjaxTask(6, '#228B22').bind(this), { on: 'init' });
  task7 = task(loopingAjaxTask(7, '#DAA520').bind(this), { on: 'init' });

  log(color, message) {
    // 通过替换数组触发响应式更新
    this.logs = [...this.logs, { color, message }].slice(-7);
  }
}

说明

  • @tracked logs:让日志数组成为响应式数据,修改后模板自动刷新
  • bind(this):确保生成器函数内的this指向组件实例,能调用log方法和访问ajaxTask
  • 调整enqueueTask参数顺序:符合ember-concurrency 2.x的API规范
  • 数组更新逻辑:用扩展运算符创建新数组,替代原有的push+set,更符合Glimmer组件的响应式规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:05:25