getify / CAF

Cancelable Async Flows (CAF)
MIT License
1.34k stars 46 forks source link

Feature request: configurable 'this' context #17

Closed chrisregnier closed 4 years ago

chrisregnier commented 4 years ago

Thanks for the great little library! I've been trying to integrate it into some of my work and found that I missing the ability to set 'this' on the generator passed to CAF. So far I've been just using bind on the generator to get around things, but I think things could be improved if CAF allowed a way of setting the bound context.

For an example on my use case:

class JobRunner {
  constructor(fooService) {
    this.fooService = fooService;

    // ***  pass in new options with context? ***
    this._runner = CAF(this.run, { context: this });
  }

  *run(signal, ...params ) {
    // do stuff in the generator but still allowed to use 'this' context of the owning class    
  }

  add(...params) {
    const token = new CAF.cancelToken();
    const result = this._runner(token.signal, ...params);
    return { token, result };
  }
}
getify commented 4 years ago

So you're saying:

f = CAF(someobj.method, { context: someobj });

...instead of:

f = CAF(someobj.method.bind(someobj));

Did I miss something?


Also, as line 61 shows, the CAF wrapped function is this sensitive, so either manual or automatic this binding should still work:

someobj.method = CAF(someobj.method);

// later
someobj.method(token);

Or:

f = CAF(someobj.method);

// later
f.call(someobj, .. );

Or:

f = CAF(someobj.method).bind(someobj);
chrisregnier commented 4 years ago

Correct. Using bind creates a new wrapping generator (and requires other support in older browsers)

someobj.method.bind(someobj)

whereas if you could pass in the context then CAF calls the generator function it could just set the context directly like this on line 194

gen.apply(context, args)
chrisregnier commented 4 years ago

oh I didn't realize you could bind the context to the return runner! Didn't know if that would be safe in case the library tried to use 'this' at all for any of its own stuff.

But ya that'll totally work for me. Thanks