All Projects → getify → Native Promise Only

getify / Native Promise Only

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

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Native Promise Only

Promise Fun
Promise packages, patterns, chat, and tutorials
Stars: ✭ 3,779 (+433.76%)
Mutual labels:  promises, polyfill
Javascript-Interview-Preparation
A curated collection of javascript interview questions & solutions.
Stars: ✭ 163 (-76.98%)
Mutual labels:  polyfill, promises
Tray
Browser plugin for sending documents and raw commands to a printer or attached device.
Stars: ✭ 543 (-23.31%)
Mutual labels:  promises
Create React Context
Polyfill for the proposed React context API
Stars: ✭ 689 (-2.68%)
Mutual labels:  polyfill
Polyfill Apcu
This component provides apcu_* functions and the APCUIterator class to users of the legacy APC extension.
Stars: ✭ 629 (-11.16%)
Mutual labels:  polyfill
Webassemblyjs
Toolchain for WebAssembly
Stars: ✭ 566 (-20.06%)
Mutual labels:  polyfill
P Map
Map over promises concurrently
Stars: ✭ 639 (-9.75%)
Mutual labels:  promises
Lwt
OCaml promises and concurrent I/O
Stars: ✭ 505 (-28.67%)
Mutual labels:  promises
Polyfill Intl Grapheme
This component provides a partial, native PHP implementation of the Grapheme functions from the Intl extension.
Stars: ✭ 690 (-2.54%)
Mutual labels:  polyfill
Polyfill Service
Automatic polyfill service.
Stars: ✭ 5,585 (+688.84%)
Mutual labels:  polyfill
Restclient
🦄 Simple HTTP and REST client for Unity based on Promises, also supports Callbacks! 🎮
Stars: ✭ 675 (-4.66%)
Mutual labels:  promises
Bootstrap Ie7
Bootstrap 3 CSS for IE7
Stars: ✭ 578 (-18.36%)
Mutual labels:  polyfill
Gray
Make an image grayscale in all browsers
Stars: ✭ 568 (-19.77%)
Mutual labels:  polyfill
Kovenant
Kovenant. Promises for Kotlin.
Stars: ✭ 657 (-7.2%)
Mutual labels:  promises
Httpie
A Node.js HTTP client as easy as pie! 🥧
Stars: ✭ 563 (-20.48%)
Mutual labels:  promises
Swiftcoroutine
Swift coroutines for iOS, macOS and Linux.
Stars: ✭ 690 (-2.54%)
Mutual labels:  promises
Resize Observer
Polyfills the ResizeObserver API.
Stars: ✭ 540 (-23.73%)
Mutual labels:  polyfill
Css Paint Polyfill
CSS Custom Paint / Paint Worklet polyfill with special browser optimizations.
Stars: ✭ 575 (-18.79%)
Mutual labels:  polyfill
Text Encoding
Polyfill for the Encoding Living Standard's API
Stars: ✭ 629 (-11.16%)
Mutual labels:  polyfill
Fetch
A window.fetch JavaScript polyfill.
Stars: ✭ 25,118 (+3447.74%)
Mutual labels:  polyfill

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/

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].