Async Class

classic Classic list List threaded Threaded
32 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Async Class

Dimitrian Nine
I cant find: was or not that proposal...

But can we have Async Class with async constructor and async super?

//AsyncClass
async_class AsyncClass { // keyword async_class(example)
constructor() {
await something(); //now constructor async too
}}

//AsyncObj in some async method
let NewAsyncObj = await AsyncClass(); // create async obj

//Extends
async_class ExtAsyncClass extends AsyncClass{
constructor() {
await super(); // now we can await super too
await something();
}}

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Async Class

Isiah Meadows-2
Is an async factory function/method not sufficient to do this? Also,
note that you *can* return promises out of the constructor (and I've
done it before).
-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Thu, Feb 15, 2018 at 11:12 PM, Dimitrian Nine
<[hidden email]> wrote:

> I cant find: was or not that proposal...
>
> But can we have Async Class with async constructor and async super?
>
> //AsyncClass
> async_class AsyncClass { // keyword async_class(example)
> constructor() {
> await something(); //now constructor async too
> }}
>
> //AsyncObj in some async method
> let NewAsyncObj = await AsyncClass(); // create async obj
>
> //Extends
> async_class ExtAsyncClass extends AsyncClass{
> constructor() {
> await super(); // now we can await super too
> await something();
> }}
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"Is an async factory function/method not sufficient to do this?"

Maybe, but i think it question similiar to "factory vs class":
we can use Сlass now, but why not to extend it to Async then?

"Also, note that you can return promises out of the constructor (and I've done it before)"

Like callback? Maybe, but again it simillial to "await vs callback" then.

I just like Class,Async and Await patterns.
And think:this some sugar can be useful for some people like me...

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

T.J. Crowder-2
On Fri, Feb 16, 2018 at 7:51 AM, Dimitrian Nine <[hidden email]> wrote:
>
> "Also, note that you can return promises out of the constructor (and I've done it before)"
>
> Like callback?

I think he means literally returning a promise. If you return an object out of the constructor, that becomes the result of the `new` operation. So you can literally return a promise of an instance instead of an instance ([fiddle][1]):

```js
class Example {
    constructor() {
        return new Promise(resolve => {
            setTimeout(() => {
                const instance = Object.create(Example.prototype);
                resolve(instance);
            }, 200);
        });
    }

    foo() {
        console.log("foo called");
    }
}
```

It gets ugly(ier) when you want to extend that. :-)

-- T.J. Crowder


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Isiah Meadows-2
 > I think he means literally returning a promise.

That would be the correct assumption. ;-)
-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Fri, Feb 16, 2018 at 3:05 AM, T.J. Crowder
<[hidden email]> wrote:

> On Fri, Feb 16, 2018 at 7:51 AM, Dimitrian Nine <[hidden email]>
> wrote:
>>
>> "Also, note that you can return promises out of the constructor (and I've
>> done it before)"
>>
>> Like callback?
>
> I think he means literally returning a promise. If you return an object out
> of the constructor, that becomes the result of the `new` operation. So you
> can literally return a promise of an instance instead of an instance
> ([fiddle][1]):
>
> ```js
> class Example {
>     constructor() {
>         return new Promise(resolve => {
>             setTimeout(() => {
>                 const instance = Object.create(Example.prototype);
>                 resolve(instance);
>             }, 200);
>         });
>     }
>
>     foo() {
>         console.log("foo called");
>     }
> }
> ```
>
> It gets ugly(ier) when you want to extend that. :-)
>
> -- T.J. Crowder
>
> [1]: https://jsfiddle.net/b9kzpd6c/1/
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"It gets ugly(ier) when you want to extend that. :-) "

Ok, i get it, but yes i prefer some more sugar like as i suggested before.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Naveen Chawla
You can just call an async method from the constructor (without await) - and then let that async method handle all the asynchronicity.

Does this satisfy your use case?

I think `async constructor` would make more sense than `async class`. Calling `new MyObjectAsync()` would have to return a promise for the object, requiring `await` to actually get the object.

My only reservation is that it does require caution not to presume that `new X()` isn't actually an instance of `X` (but that `await new X()` is). Otherwise I don't mind it.

On Fri, 16 Feb 2018 at 14:14 Dimitrian Nine <[hidden email]> wrote:
"It gets ugly(ier) when you want to extend that. :-) "

Ok, i get it, but yes i prefer some more sugar like as i suggested before.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"You can just call an async method from the constructor (without await) - and then let that async method handle all the asynchronicity." 

Not sure about it - how control? callback?
I prefer async/await then.

"I think async constructor would make more sense than async class"

Maybe: i use it for class more for difference between class and async class was more visible.
But yes in total idea about async constructor.
Both variants work for me.
What more useful - i dont sure...

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Naveen Chawla
Like this:

```js
class MyObject{
    constructor(){
        initializeAsync();
    }

    async initializeAsync(){
        await doSomething();
        await doSomethingElse();
        //etc.
    }
}
```

Of course if you wanted to await at the constructor call level (and await inside the constructor itself), e.g.

```js
    const myObject = await new MyObject();
```

...then of course you would need the "async constructor" feature, like you've requested, but then `new MyObject()` would return a promise.

Personally I have no problem with this:

It suffers from the same bug-set than you would get if you converted a synchronous function to an asynchronous one (i.e. the need to await).

On Sat, 17 Feb 2018 at 11:13 Dimitrian Nine <[hidden email]> wrote:
"You can just call an async method from the constructor (without await) - and then let that async method handle all the asynchronicity." 

Not sure about it - how control? callback?
I prefer async/await then.

"I think async constructor would make more sense than async class"

Maybe: i use it for class more for difference between class and async class was more visible.
But yes in total idea about async constructor.
Both variants work for me.
What more useful - i dont sure...
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

T.J. Crowder-2
On Sun, Feb 18, 2018 at 8:27 AM, Naveen Chawla <[hidden email]> wrote:
>
> Like this:
>
> ```js
> class MyObject{
>     constructor(){
>         initializeAsync();
>     }
>
>     async initializeAsync(){
>         await doSomething();
>         await doSomethingElse();
>         //etc.
>     }
> }
> ```

That constructor breaks one of the main rules of promises: Either handle the rejection, or propagate the promise.

-- T.J. Crowder


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Naveen Chawla
There is no rule that says you must propagate every promise. `initializeAsync` doesn't return anything, so the constructor just kicks off the async process.

On Sun, 18 Feb 2018, 2:02 pm T.J. Crowder, <[hidden email]> wrote:
On Sun, Feb 18, 2018 at 8:27 AM, Naveen Chawla <[hidden email]> wrote:
>
> Like this:
>
> ```js
> class MyObject{
>     constructor(){
>         initializeAsync();
>     }
>
>     async initializeAsync(){
>         await doSomething();
>         await doSomethingElse();
>         //etc.
>     }
> }
> ```

That constructor breaks one of the main rules of promises: Either handle the rejection, or propagate the promise.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Naveen Chawla
In the example, promise rejection can be handled with a try+catch inside `initializeAsync()` itself. But we're deviating from the topic of "async constructor", from which this is separate

On Sun, 18 Feb 2018, 2:37 pm Naveen Chawla, <[hidden email]> wrote:
There is no rule that says you must propagate every promise. `initializeAsync` doesn't return anything, so the constructor just kicks off the async process.

On Sun, 18 Feb 2018, 2:02 pm T.J. Crowder, <[hidden email]> wrote:
On Sun, Feb 18, 2018 at 8:27 AM, Naveen Chawla <[hidden email]> wrote:
>
> Like this:
>
> ```js
> class MyObject{
>     constructor(){
>         initializeAsync();
>     }
>
>     async initializeAsync(){
>         await doSomething();
>         await doSomethingElse();
>         //etc.
>     }
> }
> ```

That constructor breaks one of the main rules of promises: Either handle the rejection, or propagate the promise.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"new MyObject() would return a promise "

I have one idea about it, but not sure good or not...

async class and then newAsync

Maybe this way more good for someone...

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

T.J. Crowder-2
In reply to this post by Naveen Chawla
On Sun, Feb 18, 2018 at 9:07 AM, Naveen Chawla <[hidden email]> wrote:
>
> There is no rule that says you must propagate every promise.

I never said there was. I said you must handle rejection, or propagate the promise. Or, yes, you can ensure that the promise is never rejected, but that's not what the code I was responding to did. It left the door wide open to unhandled rejections.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Async Class

kdex
In reply to this post by Dimitrian Nine
Having the constructor return a `Promise` is generally considered bad
practice, since it breaks `new X instanceof X`, which in general breaks
inheritance.

So, for this idea to work, you really shouldn't mark `constructor` as `async`
(since this might suggest it returning a `Promise`, which it mustn't);
instead, you would have to make the constructor return `this`, then make the
asynchronous initialization, and then execute the rest. In other words,

something like this:

```js
async class X {
        constructor() {
                await this.read();
                await this.write();
        }
        async read() { … }
        async write() { … }
}
console.log(new X());
```

would transpile like so:

```js
class X {
        constructor() {}
        async initialize() {
                await this.read();
                await this.write();
        }
        async read() { … }
        async write() { … }
}
(new X()).initialize().then(x => {
        console.log(x);
});
```

The next problem with this idea is that you can't statically decide what `new
something` is about to construct. Since `something` might be an `async class`,
the StatementList following the construction of `something` would always have
to be wrapped in a callback.

Long story short, introducing this feature would slow down `new`/
`Reflect.construct`.

On Friday, February 16, 2018 5:12:10 AM CET Dimitrian Nine wrote:

> I cant find: was or not that proposal...
>
> But can we have Async Class with async constructor and async super?
>
> //AsyncClass
> async_class AsyncClass { // keyword async_class(example)
> constructor() {
> await something(); //now constructor async too
> }}
>
> //AsyncObj in some async method
> let NewAsyncObj = await AsyncClass(); // create async obj
>
> //Extends
> async_class ExtAsyncClass extends AsyncClass{
> constructor() {
> await super(); // now we can await super too
> await something();
> }}
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"Long story short, introducing this feature would slow down new/ Reflect.construct"
"since this might suggest it returning a Promise, which it mustn't "

Can it help: if async class constructor will be return Promise(obj) and i suggest before use newAsync for that practice?

Slow... but how much?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Naveen Chawla
I think `awaitNew MyObject()` would fit the thrust of your idea more. This would allow `new MyObject()` to still be an instance of the object instead of a promise, even if the constructor is async. It would dispatch the async parts of the constructor to the background instead of awaiting it. e.g.:

```js
class MyObject {
    async constructor(){
        //sync stuff
        await doAsyncStuff();
        //etc.
    }
}

const
    myObjectWithOnlySyncStuffCompleted = new MyObject(), //Gets a new instance but with only the "sync stuff" completed. Async stuff gets dispatched to the background
    myObjectWithAsyncStuffCompleted = awaitNew MyObject() //Gets a new instance with everything (including async stuff) completed
;
```

However, I have no problem the 1st version (new MyObject() returning a promise if the constructor is async). I think it's more consistent with how functions work anyway. But `awaitNew` serves the same requirement while ensuring `new MyObject()` is always an instance of `MyObject`.

On Sun, 18 Feb 2018 at 17:16 Dimitrian Nine <[hidden email]> wrote:
"Long story short, introducing this feature would slow down new/ Reflect.construct"
"since this might suggest it returning a Promise, which it mustn't "

Can it help: if async class constructor will be return Promise(obj) and i suggest before use newAsync for that practice?

Slow... but how much?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"I think awaitNew MyObject() would fit the thrust of your idea more"

For me more good my first version... async class = return Promise(obj)
But i can agree with others decisions, if in the end i get: easy way to async new

Some people ask me for some more interesting sample...
Maybe it can help - try create:
```js
//some module
async class FilterImg{
constructor(path,filters){
this.img = await load(path);
if (filters) {await this.use_filters(filters);}
}}
async use_filters(filters){
await filter1(this.image);
await filter2(this.image);
}}//class
export default FilterImg;
//end module

void async finction(){
let FilterImg = (await import(url)).default;
async class ExtFilterImg extends FilterImg{
constructor(path,filters){
await super(path);
if (filters) {await this.use_extFilters(filters);}
}}//class

let extFilter_img = await new FilterImg(path,filters);
console.log(extFilter_img.src+' '+extFilter_img.filters);
}();
```

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Isiah Meadows-2
I'm still struggling through this thread to see why a static factory
method/function with a private constructor/class doesn't suffice for
this, or in this case, just procedural functions? (That's what I
normally do, [even in ES5][1].)

```js
// filter-img.js
export async function create(path) {
    const img = await load(path)
    await filter1(img)
    await filter2(img)
    return img
}

// ext-filter-img.js
import * as FilterImg from "./filter-img.js"

async function create(path) {
    const img = await FilterImg.create(path)
    await extFilter1(img)
    await extFilter2(img)
    return img
}


(async () => {
    let ExtFilterImg = await import("./ext-filter-img.js")
    let extFilterImg = await ExtFilterImg.create(path)
    // ...
})()
```

[1]: https://github.com/isiahmeadows/thallium/blob/master/lib/cli/loader.js

-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Mon, Feb 19, 2018 at 2:49 AM, Dimitrian Nine
<[hidden email]> wrote:

> "I think awaitNew MyObject() would fit the thrust of your idea more"
>
> For me more good my first version... async class = return Promise(obj)
> But i can agree with others decisions, if in the end i get: easy way to
> async new
>
> Some people ask me for some more interesting sample...
> Maybe it can help - try create:
> ```js
> //some module
> async class FilterImg{
> constructor(path,filters){
> this.img = await load(path);
> if (filters) {await this.use_filters(filters);}
> }}
> async use_filters(filters){
> await filter1(this.image);
> await filter2(this.image);
> }}//class
> export default FilterImg;
> //end module
>
> void async finction(){
> let FilterImg = (await import(url)).default;
> async class ExtFilterImg extends FilterImg{
> constructor(path,filters){
> await super(path);
> if (filters) {await this.use_extFilters(filters);}
> }}//class
>
> let extFilter_img = await new FilterImg(path,filters);
> console.log(extFilter_img.src+' '+extFilter_img.filters);
> }();
> ```
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Async Class

Dimitrian Nine
In reply to this post by Dimitrian Nine
"why a static factory"

I answered earlier:
<<Maybe, but i think it question similiar to "factory vs class">>

Yes, you can, but for me more easy to work with classes.
And i just want to extend the functionality for work with async - that all.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12