UNPKG

async-constructor

Version:

The helper functions for creating classes that require asynchronous constructors.

152 lines (111 loc) 3.38 kB
# async-constructor [![npm](https://img.shields.io/npm/v/async-constructor.svg?maxAge=86400)](https://www.npmjs.com/package/async-constructor) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](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') ```