Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
native-promise-only
Advanced tools
Native Promise Only: A polyfill for native ES6 Promises **only**, nothing else.
The native-promise-only package is a lightweight implementation of the ES6 (ECMAScript 2015) Promise specification. It provides a way to handle asynchronous operations in JavaScript, allowing you to write cleaner and more manageable code. This package is particularly useful for environments that do not natively support Promises or for those who prefer a minimalistic implementation.
Basic Promise Usage
This code demonstrates the basic usage of a Promise. It creates a new Promise that resolves with the message 'Hello, World!' after 1 second. The .then() method is used to handle the resolved value.
const Promise = require('native-promise-only');
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Hello, World!'), 1000);
});
promise.then((message) => {
console.log(message); // 'Hello, World!'
});
Chaining Promises
This code demonstrates how to chain multiple .then() methods to handle a sequence of asynchronous operations. Each .then() method returns a new Promise, allowing for a chain of operations.
const Promise = require('native-promise-only');
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
promise
.then((value) => {
console.log(value); // 1
return value + 1;
})
.then((value) => {
console.log(value); // 2
return value + 1;
})
.then((value) => {
console.log(value); // 3
});
Handling Errors
This code demonstrates how to handle errors in Promises using the .catch() method. If the Promise is rejected, the .catch() method will be called with the error.
const Promise = require('native-promise-only');
const promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('Something went wrong!')), 1000);
});
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error.message); // 'Something went wrong!'
});
Bluebird is a fully-featured Promise library for JavaScript. It provides a wide range of additional features and optimizations compared to native-promise-only, such as cancellation, progress tracking, and more. Bluebird is known for its performance and extensive API.
Q is a library for creating and managing promises in JavaScript. It offers a rich set of features for working with asynchronous code, including utilities for dealing with collections of promises, error handling, and more. Q is more feature-rich compared to native-promise-only.
ES6-Promise is a polyfill for the ES6 Promise specification. It aims to provide a compliant implementation of Promises for environments that do not support them natively. While it is similar to native-promise-only in providing a minimalistic implementation, ES6-Promise focuses on strict compliance with the ES6 specification.
A polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.
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 (link needed).
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.
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 use the polyfill in node, 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:
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 extend
ing Promise
in the ES6 sub-class sense.
This polyfill assumes some ES5+ capabilities, such as Function#bind
and Array#forEach
. If you need to use this polyfill in pre-ES5 environments, make sure to provide polyfills/shims such as these.
Specifically, Native Promise Only needs:
Array.isArray
Array#forEach
Array#some
Function#bind
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 hidden "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!).
Native Promise Only is "spec compliant" in the sense of passing all tests in the Promises/A+ Test Suite.
To run all tests:
npm install native-promise-only
, and then switch into that project root.npm install
in the project root to install the dev-dependencies../build.js
or node build.js
or npm run build
to generate the minified "npo.js" in the project root.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.
The code and all the documentation are released under the MIT license.
FAQs
Native Promise Only: A polyfill for native ES6 Promises **only**, nothing else.
The npm package native-promise-only receives a total of 1,118,454 weekly downloads. As such, native-promise-only popularity was classified as popular.
We found that native-promise-only demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.