Example: AJAX Throttling

Limiting the number of simultaneous AJAX requests (or the number of any kind of global, shared resource) can be accomplished using the maxConcurrency task modifier.

In the example below, we render a component with 8 different concurrently running tasks that each, within an infinite loop, make (fake) AJAX requests. We've wrapped the code that actually performs the (fake) AJAX request in a task, and we've annotated that task with @task({ maxConcurrency: 3 }) to ensure that no more than 3 AJAX requests can be run at a time (so that we don't overload the browser).

Live Example

  • Task 6: making AJAX request
  • Task 5: making AJAX request
  • Task 4: making AJAX request
  • Task 3: making AJAX request
  • Task 2: making AJAX request
  • Task 1: making AJAX request
  • Task 0: making AJAX request
function loopingAjaxTask(id, color) {
  return 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 AjaxThrottlingExampleComponent extends Component {
  tagName = '';
  logs = [];

  @enqueueTask({ maxConcurrency: 3 })
  *ajaxTask() {
    // simulate slow AJAX
    yield timeout(2000 + 2000 * Math.random());
    return {};
  }

  @task({ on: 'init' }) task0 = loopingAjaxTask(0, '#0000FF');
  @task({ on: 'init' }) task1 = loopingAjaxTask(1, '#8A2BE2');
  @task({ on: 'init' }) task2 = loopingAjaxTask(2, '#A52A2A');
  @task({ on: 'init' }) task3 = loopingAjaxTask(3, '#DC143C');
  @task({ on: 'init' }) task4 = loopingAjaxTask(4, '#20B2AA');
  @task({ on: 'init' }) task5 = loopingAjaxTask(5, '#FF1493');
  @task({ on: 'init' }) task6 = loopingAjaxTask(6, '#228B22');
  @task({ on: 'init' }) task7 = loopingAjaxTask(7, '#DAA520');

  log(color, message) {
    let logs = this.logs;
    logs.push({ color, message });
    this.set('logs', logs.slice(-7));
  }
}