Write code like a story w/ a powerful Fluent (function chaining) API
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.vscode Implement `.quiet(threshold)` (#39) Feb 24, 2018
dist RELEASE: v1.7.1 - minor docs fix Sep 22, 2018
docs-source
docs
misc
src
tests minor test update Sep 22, 2018
.babelrc WIP: progress Sep 21, 2018
.eslintrc
.gitignore
.npmignore
.travis.yml update travis - swap node v9 -> v10 Sep 22, 2018
CODE_OF_CONDUCT.md
LICENSE
PITCHME.md
PITCHME.yaml
README.md
index.d.ts WIP: Adding tests for #44 Jul 25, 2018
package-lock.json
package.json
publish.sh
stats-loc.yml
tsconfig.json
webpack.config.js

README.md

Functional Promises

Build Status GitHub package version GitHub stars

Updated Documentation: fpromises.io

New Docs

Summary

The Functional Promises library is a Fluent API supporting a specific Function Chaining technique (using composition).

Note: FP doesn't replace or extend Promises. It uses them.

There are many names for this general pattern. Including Collection Pipeline and Promise Chain. The emphasis here is a seamless async/sync Developer Experience.

I call this pattern a Functional River - your data is the water, and your functions describe its path or riverbed.

Advantages

  • Only 400 Lines of Source & 4Kb Gzipped
  • Easily handle Sync, Async, Events, Promises, and Callbacks.
  • Familiar methods, including Array.prototype.map, [].filter(), [].find(), [].some(), etc.
  • Create Monads in JavaScript (so far as they contain side-effects to a sequence of instructions).
  • Point-free code is easily achieved (no temp variables).
  • Higher code test coverage w/ less repetitive code in tests.
  • Use the best features from multiple programming styles: a little imperative, plenty functional, a pinch of OOP, yet still resembling declarative methods!!!

Library Comparison

Total Lines of Code (LoC) calculated using cloc CLI utility.

LoC #'s included because a smaller surface === fewer places bugs can hide.

Library Main deal Files Lines of Code .min.js kB
Functional Promise v1.5.3 Sync & Async Chains 8 375 16 Kb (4Kb gzip)
Bluebird v3.5.1 Promises Replacement 38 5,188 80 Kb
RxJS v5.5.6 Observables Chaining 458 12,266 150 Kb
IxJS v2.3.4 [Async]Iterable Chaining 521 12,366 145 Kb

Admittedly IxJS/RxJS have a far larger API than FP also some behavior in RxJS/IxJS may never be added. Currently however there is a lot of overlap with FP (plus more planned).

The table above show FP is roughly 1/30th the LOC (lines of code) in R/IxJs. FP's bundle size is about 10% the size of either RxJS/IxJS.

BluebirdJS and FP have roughly the same number of API methods, yet Bluebird has a fair bit more code.

To be clear: Bluebird and RxJS/IxJS are amazing. Their interface/designs has been very influential on FP.

Note: R/IxJS's hyper-modular design also allows for bundles to be lots smaller (though using quite different syntax, either .pipe(...) or ix/iterable/ix/add/...).

Installation

npm install functional-promise

Getting Started

Use one of the following:

const FP = require('functional-promise')
// or:
import FP from 'functional-promise'

Quick Examples

Using .map()

FP.resolve([1, 2, 3, 4, 5])
  .map(x => x * 2)
  .map(x => x * 2)
  .then(results => {
    // results === [4, 8, 12, 16, 20]
  })

Handling Events

Create function chains to handle the case where promises don't fit very naturally.

For example streams & event handlers must (usually) support multiple calls over time.

Here's how FP.chain() and FP.chainEnd()/FP.listen(obj, event) help you handle this like a pro:

const button = document.getElementById('submitBtn')
FP.chain() // start a chain
  .then(({target}) => { // destructure 'target' from the `event`
    target.textContent = 'Clicked!'
  })
  .listen(button, 'click') // end the repeatable chain, started at `.chain()`

API Outline

Development

git clone git@github.com:functional-promises/functional-promises.git
cd functional-promises
npm install
npm test

Thanks to several influencial projects: RxJS, IxJS, Bluebird, asynquence, FantasyLand, Gulp, HighlandJS, et al.

Special thanks to Kyle Simpson, Eric Elliot, and Sarah Drasner for their work for the OSS community, as well as their advice & encouragement.