• This repository has been archived on 31/Dec/2022
  • Stars
    star
    725
  • Rank 61,229 (Top 2 %)
  • Language
    JavaScript
  • Created about 10 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.

Native Promise Only (NPO)

CDNJS

A polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.

Intent

The aim of this project is to be the smallest polyfill for Promises, staying as close as possible to what's specified in both Promises/A+ and the upcoming ES6 specification.

An equally important goal is to avoid exposing any capability for promise-state to be mutated externally. The Known Limitations section below explains the trade-offs of that balance.

Usage

To use this polyfill in the browser, include the "npo.js" file (see the instructions in Tests/Compliance section below for how to build "npo.js" if you don't have it already) with your site's scripts. It's a polyfill, which means it will not overwrite Promise if it exists as a global already, so it's safe to include unconditionally.

To use with AMD, import the "npo.js" file module.

To install the polyfill via bower, run:

bower install native-promise-only

To install the polyfill via npm, run:

npm install native-promise-only

Then require the module into your node code:

require("native-promise-only");

Notice that using the module in this way, we don't assign the module's public API to any variable. We don't need to, because it's a polyfill that intentionally patches the global environment (in this case to the Promise name) once included.

If you want to also have a reference pointing to the same Promise global, you can also assign the return value from the require(..) statement, but it's strongly recommended that you use the same Promise name so as to not create confusion:

var Promise = require("native-promise-only");

// Promise === global.Promise; // true!

Other than the below Known Limitations discussion and some browser bugs (such as these) which this polyfill doesn't suffer from, your promises should operate the same in all JS environments.

Exactly like native promises, here's a quick example of how you create and use the polyfilled promises:

var p = new Promise(function(resolve,reject){
	setTimeout(function(){
		resolve("Yay!");
	},100);
});

p.then(function(msg){
	console.log(msg); // Yay!
});

For more on promises, check these blog posts out:

  1. Back-story on the hows and whys behind promises (chaining, errors, etc): multi-part blog post series "Promises" by getify (me).
  2. Using and enjoying native promises: JavaScript Promises by Jake Archibald.

Known Limitations

A promise object from this polyfill will be an instance of the Promise constructor, which makes identification of genuine promises easier:

var p = new Promise(..);

p instanceof Promise; // true

However, these promise instances don't inherit (delegate to) a meaningful Promise.prototype object for their methods (there is one, it's just mostly empty).

Consider:

var p = new Promise(..);

Object.getOwnPropertyNames( p ); // [ then, catch ]
Object.getOwnPropertyNames( Promise.prototype ); // [ constructor ]

As such, these promises are not really "sub-classable" in the ES6 class / extends sense, though theoretically you should be able to do that in ES6 with the built-in Promises.

To read a full explanation of why, read Part 3: The Trust Problem of my blog post series on Promises.

Briefly, the reason for this deviation is that there's a choice between having delegated methods on the .prototype or having private state. Since the spirit of promises was always to ensure trustability -- that promises were immutable (from the outside) to everyone except the initial resolver/deferred -- private state is a critically important feature to preserve.

Many other ES6 promise shims/libs seem to have forgotten that important point, as many of them either expose the state publicly on the object instance or provide public accessor methods which can externally mutate a promise's state. Both of these deviations are intolerable in my opinion, so this library chose the opposite trade-off: no ES6 sub-classing.

Any trade-off is a shame, but this one is the least of a few evils, and probably won't prove to limit very many, as there are only a limited number of use-cases for extending Promise in the ES6 sub-class sense.

Still Want More?

This project intentionally adheres pretty strictly to the narrow core of Promises/A+ as adopted/implemented by ES6 into the native Promise() mechanism.

But it's quite likely that you will experience a variety of scenarios in which using only native promises might be tedious, limiting, or more trouble than it's worth. There's good reason why most other Promises/A+ "compliant" libs are actually superset extensions on the narrow core: because async flow-control is often quite complex in the real world.

Native Promise Only will NOT add any of these extra flourishes. Sorry.

However, I have another project: asynquence (async + sequence). It's an abstraction on top of the promises concept (promises are hidden inside), designed to drastically improve the readability and expressiveness of your async flow-control code.

You simply express your async flow-control and asynquence creates and chains all the promises for you underneath. Super simple.

asynquence has a custom implementation for the internal "promises" it uses, and as such does not need native Promises, nor does it need/include this polyfill.

Get your feet wet with native promises first, but then when you go looking for something more, consider asynquence (which is vastly more powerful and is still only ~2k!).

Tests/Compliance

Promises/A+ logo

Native Promise Only is "spec compliant" in the sense of passing all tests in the Promises/A+ Test Suite.

To run all tests:

  1. Either git-clone this repo or run npm install native-promise-only, and then switch into that project root.
  2. Run npm install in the project root to install the dev-dependencies.
  3. If you didn't get native-promise-only from npm, then from the project root, run ./build.js or node build.js or npm run build to generate the minified "npo.js" in the project root.
  4. Finally, run npm test.

Note: Other tests need to be added, such as testing the Promise() constructor's behavior, as well as the Promise.* static helpers (resolve(..), reject(..), all(..), and race(..)), none of which are covered by the Promises/A+ test suite.

Developing a more comprehensive test-suite to augment the Promises/A+ test suite is now another primary goal of this project.

License

The code and all the documentation are released under the MIT license.

http://getify.mit-license.org/

More Repositories

1

You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter.
177,328
star
2

Functional-Light-JS

Pragmatic, balanced FP in JavaScript. @FLJSBook on twitter.
JavaScript
16,518
star
3

LABjs

Loading And Blocking JavaScript: On-demand parallel loader for JavaScript with execution order dependencies
HTML
2,277
star
4

asynquence

Asynchronous flow control (promises, generators, observables, CSP, etc)
JavaScript
1,740
star
5

CAF

Cancelable Async Flows (CAF)
JavaScript
1,327
star
6

monio

The most powerful IO monad implementation in JS, possibly in any language!
JavaScript
1,041
star
7

TNG-Hooks

Provides React-inspired 'hooks' like useState(..) for stand-alone functions
JavaScript
1,011
star
8

A-Tale-Of-Three-Lists

Comparing various async patterns for a single demo
JavaScript
650
star
9

fasy

FP iterators that are both eager and asynchronous
JavaScript
544
star
10

FPO

FP library for JavaScript. Supports named-argument style methods.
JavaScript
448
star
11

youperiod.app

YouPeriod.app -- the privacy-first period tracking app
JavaScript
443
star
12

JSON.minify

Simple minifier for JSON to remove comments and whitespace
405
star
13

TypL

The Type Linter for JS
JavaScript
365
star
14

h5ive-DEPRECATED

**DEPRECATED** A collection of thin facade APIs wrapped around HTML5 JavaScript features.
JavaScript
324
star
15

eslint-plugin-proper-arrows

ESLint rules to ensure proper arrow function definitions
JavaScript
305
star
16

foi-lang

Foi: a different kind of functional programming language
JavaScript
302
star
17

grips

Simple-logic templates
JavaScript
287
star
18

moduloze

Convert CommonJS (CJS) modules to UMD and ESM formats
JavaScript
205
star
19

ES-Feature-Tests

Feature Tests for JavaScript
JavaScript
199
star
20

let-er

DEPRECATED: Transpile non-ES6 let-blocks into ES6 (or ES3)
JavaScript
192
star
21

Incomplete-JS

"The Incomplete Guide to JavaScript" (book). @IncompleteJS on twitter.
190
star
22

revocable-queue

Specialized async queue data structure, supports revocation of values
JavaScript
176
star
23

deePool

highly-efficient pool for JavaScript objects
JavaScript
115
star
24

getify.github.io

JavaScript
109
star
25

concrete-syntax-tree

Defining a standard JavaScript CST (concrete syntax tree) to complement ASTs
107
star
26

eslint-plugin-proper-ternary

ESLint rules to ensure proper usage of ternary/conditional expressions
JavaScript
95
star
27

cloud-sweeper

A casual game built for the web.
JavaScript
93
star
28

BikechainJS

JavaScript VM engine (powered by V8); server-side environment modules; server-side synchronous web app controllers
C++
81
star
29

wepuzzleit

Demo PoC game for various advanced HTML5 js APIs
JavaScript
78
star
30

workshop-periodic-table

65
star
31

elasi

EL/ASI: Encrypt Locally, Account Secure Interchange
JavaScript
60
star
32

remote-csp-channel

Remote bridge for CSP channels
JavaScript
55
star
33

ScanTree

Scan a JS file tree to build an ordered and grouped dependency listing
JavaScript
51
star
34

dwordly-game

A game where words dwindle down to the shortest possible
JavaScript
42
star
35

stable-timers

timers with less race conditions
JavaScript
38
star
36

emdash

Simple blogging with node/iojs + GitHub.
36
star
37

domio

DOM and Event helpers for Monio
JavaScript
30
star
38

eslint-plugin-no-optional-call

ESLint plugin to disallow the optional-call operator
JavaScript
30
star
39

eslint-plugin-arrow-require-this

DEPRECATED: ESLint rule to require arrow functions to reference the 'this' keyword
JavaScript
28
star
40

import-remap

Rewrite ES module import specifiers using an import-map.
JavaScript
25
star
41

gum-try-hd

Try to enforce HD (16:9) camera aspect ratio for web-video calls
JavaScript
25
star
42

Mock-DOM-Resources

A mock of (parts of) the DOM API to simulate resource preloading and loading
JavaScript
25
star
43

make-a-game

some project files for a tutorial on making a simple web game
JavaScript
24
star
44

mpAjax

framework plugin for handling multi-part Ajax responses
JavaScript
23
star
45

asyncGate.js

DEPRECATED. asynchronous gate for javascript
JavaScript
21
star
46

tic-tac-toe-workshop

Workshop files for building tic-tac-toe in JS and <canvas>
21
star
47

esre

esre: fully configurable JS code formatting
20
star
48

workshop-chess-diagonals

17
star
49

featuretests.io

JavaScript Feature Tests... as a service
JavaScript
16
star
50

FoilScript

FoilScript: a new dialect of JS that fixes the sucky parts but still looks and feels like JS
16
star
51

literalizer

Specialized heuristic lexer for JS to identify complex literals
JavaScript
15
star
52

normalize-selector

Normalize CSS selectors
JavaScript
14
star
53

DOMEventBridge

Bridge DOM events to a JS event hub (for pubsub)
JavaScript
14
star
54

pong-around-workshop

Workshop files for building a pong-variant game in JS and <canvas>
12
star
55

shortie.me

Proof-of-concept demo for server-side JavaScript driven "middle-end" architecture
JavaScript
11
star
56

workshop-wordy-unscrambler

10
star
57

middleend-boilerplate

Boilerplate Starting Point for Middle-end Web Architecture
JavaScript
8
star
58

workshop-knights-dialer

7
star
59

demo-app-weatheround

JavaScript
7
star
60

the-economy-of-keystrokes-slides

Slides code built for "The Economy of Keystrokes" talk
JavaScript
6
star
61

santa-connect-app

Santa Connect: keeping track of your kids' nice/naughty status
JavaScript
5
star
62

nyc-bug-demo

bug demo for NYC code coverage tool
JavaScript
5
star
63

unnamed

unnamed (for now). nothing to see here. ;-)
JavaScript
2
star
64

my-lifesheets

CSS
1
star
65

breakthewebforward.com

JavaScript
1
star