# golike-defer

> go's defer statement in JavaScript

Latest version **0.5.1** (published 2021-02-25) · ISC license · 0 weekly downloads

## Install

```sh
npm install golike-defer
pnpm add golike-defer
yarn add golike-defer
bun add golike-defer
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.5.1 |
| Published | 2021-02-25 |
| First published | 2016-11-30 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=4 |
| Dependencies | 0 |
| Unpacked size | 18.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 10 |
| Author | Julien Fontanet |
| Maintainers | julien-f, marsaud, pdonias |
| Keywords | clean, clean-up, cleanup, defer, deferrable, finally, go, teardown |

## Links

- npm: https://www.npmjs.com/package/golike-defer
- Repository: https://github.com/JsCommunity/golike-defer
- Issues: https://github.com/JsCommunity/golike-defer/issues
- npm.io page: https://npm.io/package/golike-defer

## Alternatives

- [angular-pipes](https://npm.io/package/angular-pipes.md) — 5.6K weekly downloads
- [@ng-web-apis/midi](https://npm.io/package/@ng-web-apis/midi.md) — 2.6K weekly downloads
- [happn-3](https://npm.io/package/happn-3.md) — 1.6K weekly downloads
- [@opensip-cli/lang-go](https://npm.io/package/@opensip-cli/lang-go.md) — 1.2K weekly downloads
- [mongoose-typescript](https://npm.io/package/mongoose-typescript.md) — 85 weekly downloads

## Recent versions

- 0.5.1 (latest) — 2021-02-25
- 0.5.0 — 2021-02-22
- 0.4.1 — 2017-12-20
- 0.4.0 — 2017-12-20
- 0.3.0 — 2017-07-17
- 0.2.0 — 2017-06-30
- 0.1.0 — 2017-05-22
- 0.0.0 — 2016-11-30

## README

# golike-defer

[![Node compatibility](https://badgen.net/npm/node/golike-defer)](https://npmjs.org/package/golike-defer) [![PackagePhobia](https://badgen.net/packagephobia/install/golike-defer)](https://packagephobia.now.sh/result?p=golike-defer)

[![Package Version](https://badgen.net/npm/v/golike-defer)](https://npmjs.org/package/golike-defer) [![Build Status](https://travis-ci.org/JsCommunity/golike-defer.png?branch=master)](https://travis-ci.org/JsCommunity/golike-defer) [![Latest Commit](https://badgen.net/github/last-commit/JsCommunity/golike-defer)](https://github.com/JsCommunity/golike-defer/commits/master)

> go's defer statement in JavaScript

`defer()` is a function decorator which injects a `$defer()` function
as a first parameter.

This injected function can be used to register _deferreds_, functions
which will be executed at the end of the decorated function execution,
no matter how it ended (via a `return` or a `throw`).

> Note: the deferreds are executed in the reverse order of their
> declarations.

## Install

Installation of the [npm package](https://npmjs.org/package/golike-defer):

```
> npm install --save golike-defer
```

## Usage

```js
import { defer } from 'golike-defer'

const fn = defer(
  // Works both with sync and async functions
  async function($defer, ...args) {
    $defer(() => {
      console.log("always called at the end of the function");
    });

    $defer.onFailure(() => {
      console.log("called at the end of the function only on failure");
    });

    $defer.onSuccess(() => {
      console.log("called at the end of the function only on success");
    });
  }
);
```

Context and arguments can be passed to the deferred function:

- `$defer(cb)`: called without context nor arguments
- `$defer(cb, arg1, arg2)`: called with arguments `arg1` and `arg2`
- `$defer.call(thisArg, cb)`: called with context `thisArg`
- `$defer.call(thisArg, 'method')`: `thisArg.method` called with context `thisArg`

## Example

```js
import { defer } from 'golike-defer'
import fs from 'fs'

const readFileSync = defer(($defer, path) => {
  const fd = fs.openSync(path, 'r')

  // The file will be automatically closed at the end of the function,
  // whether it succeed or failed.
  $defer(fs.closeSync, fd)

  const { size } = fs.statSync(path)

  const buffer = Buffer.allocUnsafe(size)
  fs.readSync(fd, buffer, 0, buffer.length)

  return buffer
})

// Helper to promisify a function call.
const fromCallback = fn => new Promise((resolve, reject) => {
  fn((error, result) => error ? reject(error) : resolve(result))
})

const readFile = defer(async ($defer, path) => {
  const fd = await fromCallback(cb => fs.open(path, 'r', cb))

  // The file will be automatically closed at the end of the function,
  // whether it succeed or failed.
  $defer(() => fromCallback(cb => fs.close(fd, cb)))

  const { size } = await fromCallback(cb => fs.stat(path, cb))

  const buffer = Buffer.allocUnsafe((size)
  await fromCallback(cb => fs.read(fd, buffer, 0, buffer.length, cb))

  return buffer
})
```

### On error

Exceptions (or rejected promises) thrown in deferred are caught and
printed on the console.

This can be customized with the `onError()` method:

```js
const myDefer = defer.onError(error => {
  log(error);
});

const fn = myDefer(($defer, arg1, arg2) => {
  // ...
});
```

## Contributions

Contributions are _very_ welcomed, either on the documentation or on
the code.

You may:

- report any [issue](https://github.com/JsCommunity/golike-defer/issues)
  you've encountered;
- fork and create a pull request.

## License

ISC © [Julien Fontanet](https://github.com/julien-f)

---
_Source: https://npm.io/package/golike-defer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
