Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

async setters? #82

Closed
mariusGundersen opened this issue Dec 26, 2015 · 4 comments
Closed

async setters? #82

mariusGundersen opened this issue Dec 26, 2015 · 4 comments

Comments

@mariusGundersen
Copy link

I stumbled on a strange issue where I needed to return a promise from a setter:

export class Something{
  get config(){
    return fs.readFile('config.json').then(json => JSON.parse(json));
  }
  set config(value){
    const content = JSON.stringify(value, null, '  ');
    return fs.writeFile('config.json', content);
  }
}

The getter works alright, since I can return a promise of a value from the getter, rather than the value. But this doesn't work with a setter, since I can't return anything from the setter. This means I can't await the writing of the file. This would work if the setter (and symmetrically the getter) could be async, like so:

export class SomethingAsync{
  async get config(){
    const json = await fs.readFile('config.json');
    return JSON.parse(json);
  }
  async set config(value){
    const content = JSON.stringify(value, null, '  ');
    await fs.writeFile('config.json', content);
  }
}

Setters return the value being set in expressions, so

const something = new Something();
const object = {};
const result = something.config = object;
//result === object

This could be tweaked for async setters, so they return a promise instead:

const somethingAsync = new SomethingAsync();
const object = {};
const result = await (somethingAsync.config = object);
//result === object

Has this been considered?

@domenic
Copy link
Member

domenic commented Dec 26, 2015

This would be bizarre. This would mean that the value of somethingAsync.config = object is not object. That would be a deep violation of ES semantics. I doubt anyone has ever considered it, but I can't imagine they would do so for more than a moment. Think of all the damage that would do to minifiers and probably optimizers.

@ljharb
Copy link
Member

ljharb commented Dec 26, 2015

To me, this seems like one of the many scenarios where getters and setters just aren't appropriate. Normal functions will work great here.

@bterlson
Copy link
Member

Definitely not in this version, but it can be considered for the future. I tend to agree though that returning anything other than the rval from an assignment expression is very questionable.

@claytongulick
Copy link

claytongulick commented Mar 20, 2020

I can think of a scenario where this would make sense to do - running into one now, actually.

I've made a Proxy which uses json-patch for isomorphism. The setters track modifications and eventually batch operations and sync with the server via json-patch.

I think it would be useful to have the semantic of:

async set first_name(value) {
  await ...
}

and something.first_name == promise until resolved, maybe:
await something.first_name = 'Fred';

Perhaps async setters wouldn't enumerate as a property the same way others would, to avoid problems with JSON.stringify and such?

My workaround for now is event dispatching, but doing that in 2020 feels very legacy.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants