Promise syntactic sugar
No need to write .then
in your promise chains.
The promise is the .then
function itself!
What it does
1 ) It allows you to convert this
Promise.resolve(10)
.then((n) => n / 2)
.then((n) => n * 3)
.then(log) // -> 15
.catch(logError)
into this
sweeten(10)
((n) => n / 2)
((n) => n * 3)
(log) // -> 15
(null, logError) // or .catch(logError)
2 ) and this
// Given two existing promises A and B
// wait for A and B and return B's value
log(await A.then(() => B)) // -> B's value
into this
log(await A(B)) // -> B's value
where
const log = console.log.bind(console);
const logError = console.error.bind(console);
That's almost it! For More sugar see below.
A sweeten promise is still a thenable.
Thus you can still await
for it, or you could swap the Promise
with the sweeten
version in your old code and it should still work the same.
Promise-sugar tries to preserve all other behaviors of the Promise
library used.
There is another library that implements a similar paradigm - thunks.
Thunks is different from Promise-sugar and more complex (a thunk is not a promise and it has no .catch()
method).
You can play with it on jsBin
Install
- Copy
promise-sugar.js
to your project or install it using npm:
npm install promise-sugar --save
- Import
promise-sugar.js
into your app usingimport
(ESM),require
(AMD or CommonJs) or as a script tag.
import sweeten from 'promise-sugar';
const sweeten = require('promise-sugar');
<script src="https://unpkg.com/promise-sugar"></script>
- Make sure there is a
Promise
implementation or get a polyfill like es6-promise.
sweeten.usePromise(require('es6-promise').Promise); // polyfill
More sugar
Regardless of the Promise
implementation used, all sweeten promises have the following methods:
sweeten(promise)
.catch(onReject) // Promite/A+
.finally(callback) // not a Promise/A+ method
.timeout(1000) // reject in 1 sec, not a Promise/A+ method
If Promise.prototype.progress
is defined, Promise-sugar will preserve it.
Here are some helper methods of Promise-sugar:
sweeten.when(value_or_thenable); // creates a sweeten promise
let deferred = sweeten.defer(); // creates a deferred with a sweeten .promise
sweeten.allValues(obj); // Similar to Promise.all(list), but accepts an object with thenable values
if(sweeten.isThenable(any)) any.then(doStuff);
let waiter = sweeten.wait(123); // setTimeout()
waiter.then(doStuffLater);
waiter.stop(); // don't doStuffLater() (like clearTimeout())
function sum(a,b) { return a + b; }
let ssum = sweeten.fn(sum); // sweeten version of sum()
ssum(2, Promise.resolve(3))(log); // -> 5
// Promise/A+ sweet equivalents
sweeten.resolve(val)
sweeten.reject(val)
sweeten.race(list)
sweeten.all(list)
sweeten.any(list)
sweeten.allSettled(list)
Examples
Sweeten promises are just promises and functions (then
s) at the same time:
let result = sweeten(fetch('/my/api'))
((res) => res.json())
;
// Now you have a simple function that contains your result
result(log);
// and it is still a promise!
result.catch(logError);
// and can be used as such
Promise.all([result, fetch('my/api/something/else')])
.then(/*...*/);
// or equivalent of the above
sweeten.all([result, fetch('my/api/something/else')])
(/*...*/);
Sweeten promise constructor:
let myStuff = new sweeten(function (resolve, rejext){
setTimeout(resolve, 100, Math.random());
});
myStuff((myNumber) => {/*...*/}, (error) => {/*...*/});