ember-concurrency icon indicating copy to clipboard operation
ember-concurrency copied to clipboard

Feature request - New attribute @runOnce - for tasks that should run only once

Open ondrejsevcik opened this issue 3 years ago • 1 comments

Hi,

in our app, we use following pattern where we load data only once quite a lot.

Here is an example

// services/user-session.js
loadData: task(...).drop(),

async loadOnce() {
  if (this.loadData.last || this.loadData.isRunning) {
    await this.loadData.last;
    return;
  }
  await this.loadData.perform();
  return;
}

and then in our components and routes, we can call await userSession.loadOnce() and do not worry to make accidentally multiple requests against our server.


It would be nice to have this baked-in into this library so that we can just add this modifier directly on the task itself.

loadData: task(...).runOnce(); // could be also called .onlyOnce()

What do you think?

ondrejsevcik avatar Mar 24 '21 11:03 ondrejsevcik

One thing I've seen before is adding the check within the task, something like:

@dropTask *myTask() {
  if (this.myTask.lastSuccessful?.value) {
    return this.myTask.lastSuccessful?.value;
  }
  
  // ... other stuff
}

This will basically ensure the same result is carried forward every time the task runs. If you were to run cancelAll({ resetState: true }) on the task, you would then clear out the lastSuccessful state and be able to recompute it, if that's useful too.

I'm working on an RFC for user-definable modifiers, and this seems like maybe a good space for that, rather than inclusion within core ember-concurrency, as I'm not sure how broadly applicable it is, other than the one-time data loading case. (I do think it's useful though!)

maxfierke avatar Mar 30 '21 15:03 maxfierke