[![npm](https://img.shields.io/npm/v/one-time-execution-method.svg)](https://www.npmjs.com/package/one-time-execution-method)
[![License](https://img.shields.io/badge/License-0BSD-blue.svg)](https://spdx.org/licenses/0BSD.html)
[![Typed with TypeScript](https://flat.badgen.net/badge/icon/Typed?icon=typescript\&label\&labelColor=blue\&color=555555)](https://typescriptlang.org)
[![bundlejs](https://deno.bundlejs.com/?q=one-time-execution-method\&badge=detailed)](https://bundlejs.com/?q=one-time-execution-method)
[![downloads](http://img.shields.io/npm/dm/one-time-execution-method.svg?style=flat-square)](https://npmjs.org/package/one-time-execution-method)
[![GitHub Issues](https://img.shields.io/github/issues/arlac77/one-time-execution-method.svg?style=flat-square)](https://github.com/arlac77/one-time-execution-method/issues)
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Farlac77%2Fone-time-execution-method%2Fbadge\&style=flat)](https://actions-badge.atrox.dev/arlac77/one-time-execution-method/goto)
[![Styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![Known Vulnerabilities](https://snyk.io/test/github/arlac77/one-time-execution-method/badge.svg)](https://snyk.io/test/github/arlac77/one-time-execution-method)
[![Coverage Status](https://coveralls.io/repos/arlac77/one-time-execution-method/badge.svg)](https://coveralls.io/github/arlac77/one-time-execution-method)

# one-time-execution-method

Define methods that will be executed only once.

For async functions the resulting Promise of the 1st. invocation will be preserved and always delivered in the future.

# example

<!-- skip-example -->

```javascript
import { replaceWithOneTimeExecutionMethod } from "one-time-execution-method";

class MyClass {
  constructor() {
    this.executions = 0;
  }

  initialize() {
    this.executions++;
    return new Promise(resolve => setTimeout(resolve, 1000));
  }
}

// replace initialize() method of MyClass to be executed only once
replaceWithOneTimeExecutionMethod(MyClass.prototype, "initialize");

async doit() {
  const object = new MyClass();

  // start several initializations in parallel
  Promise.all([object.initialize(), object.initialize(), object.initialize()]);

  await object.initialize();

  // even after several parallel executions only one run is done
  console.log(this.executions); // -> 1
}

doit();
```

# API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

*   [replaceWithOneTimeExecutionMethod](#replacewithonetimeexecutionmethod)
    *   [Parameters](#parameters)
*   [transitionState](#transitionstate)

## replaceWithOneTimeExecutionMethod

Replace a given method with one that will only be executed once.
For async functions the resulting Promise of the 1st. invocation
will be preserved and always delivered in the future.

```js
class MyClass {
  async initialize() {
   // code here will be executed only once
  }
}
replaceWithOneTimeExecutionMethod(MyClass.prototype, "initialize");

const object = new MyClass();
object.initialize(); // body will/can be executed only once
object.initialize(); // 2nd. call immediatly returns
```

### Parameters

*   `object` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** prototype to bind method against
*   `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** of the method

## transitionState

Object symbol slot holding the state of the method.

*   undefined -> call func and store Promise
*   Promise   -> func currently running or fullfilled -> deliver this Promise

# install

With [npm](http://npmjs.org) do:

```shell
npm install one-time-execution-method
```

# license

BSD-2-Clause
