async-constructor
Version:
The helper functions for creating classes that require asynchronous constructors.
152 lines (111 loc) • 3.38 kB
Markdown
# async-constructor [](https://www.npmjs.com/package/async-constructor) [](https://raw.githubusercontent.com/BlackGlory/async-constructor/master/LICENSE)
The helper functions for creating classes that require async constructors.
## Install
```sh
npm install --save async-constructor
# or
yarn add async-constructor
```
## Usage
This module is created for [TypeScript](#TypeScript), but can also be used in [JavaScript](#JavaScript).
### JavaScript
You may not need the module because JavaScript constructor could return a `Promise<this>`:
```js
class Resource {
constructor(url) {
return (async () => {
this.content = await load(url)
return this
})()
}
}
```
or
```js
function Resource(url) {
return (async () => {
this.content = await load(url)
return this
})()
}
```
### TypeScript
#### AsyncConstructor
##### ES2017
```ts
import { AsyncConstructor } from 'async-constructor'
class Resource extends AsyncConstructor {
content!: string
constructor(url: string) {
super(async () => {
this.content = await load(url)
})
}
}
const resource = await new Resource('data.txt')
```
##### ES2015
```ts
import { AsyncConstructor } from 'async-constructor/lib/es2015'
class Resource extends AsyncConstructor {
content!: any
constructor(url: string) {
super(async function(this: Resource) {
this.content = await load(url)
})
}
}
;(async () => {
const resource = await new Resource('data.txt')
})()
```
#### appendAsyncConstructor
```ts
function appendAsyncConstructor<T, U extends any[]>(
target: T
, asyncConstructor: (...args: U) => PromiseLike<void>
, args?: U
): void
```
Once a class has an async constructor, its subclasses will also have async constructors.
The function `AsyncConstructor` is a wrapper for `appendAsyncConstructor`, you can call `appendAsyncConstructor` in the sync constructor to append an async constructor.
```js
import { appendAsyncConstructor } from 'async-constructor'
class Resource {
content!: string
constructor(url: string) {
appendAsyncConstructor(this, async () => {
this.content = await load(url)
})
}
}
class DataResource extends Resource {
constructor(append: string) {
super('data.txt')
appendAsyncConstructor(this, async () => {
this.content += append
})
}
}
const resource = await new DataResource('\n')
```
The multiple async constructors will be called in order, and always called after all sync constructor.
#### mixinAsyncConstructor
```ts
function mixinAsyncConstructor<Base extends Constructor>(
base: Base
, asyncConstructor: (...args: ConstructorParameters<Base>) => PromiseLike<void>
): new (...args: ConstructorParameters<Base>) => PromiseLike<ReturnTypeOfConstructor<Base>>
```
The mixin function `mixinAsyncConstructor` is also used to add async constructors to classes, but you cannot access protected/private member in the async constructor.
```ts
import { mixinAsyncConstructor } from 'async-constructor'
class Base {
content!: string
constructor(url: string) {}
}
const Resource = mixinAsyncConstructor(Base , async function(this: Base, url) {
this.content = await load(url)
})
const resource = await new Resource('data.txt')
```