There are a few ways to create promises using Vachan. The first is to directly create a promise object as shown below.
new P(executor)
const { P } = require("vachan");
const fs = require("fs");
function delayedCopy(file1,file2,delay)
{
return new P(
(resolve,reject) => {
fs.readFile(file1,(err,data)=>{
if(err) reject(err);
else setTimeout(()=>{
fs.writeFile(file2,data,(err)=>{
if(err) reject(err);
resolve();
});
},delay);
});
}
);
}
delayedCopy("one.txt","two.txt",2000)
.then(
() => console.log("Success"),
err => console.log("Failure")
);
The second way of creating promises where the value is predetermined/known ahead of time is through two static methods of P class i.e. P.resolve(value)
and P.reject(value)
. There is also a delay function P.delay(value,time)
it is a special variation of resolve which allows a promise with predetermined value to resolve after a delay.
P.resolve(value), P.reject(value) and P.delay(value,time)
const { P } = require("vachan");
console.log(P.resolve(10));
console.log(P.reject(new Error("Test!")));
P.delay("Late!",500).then(console.log);
The last way is to wrap existing Node.js APIs with vachanify function which automatically promisfies them on which you can chain.
P.vachanify(function)
const { P } = require("vachan");
const fs = require("fs");
const read = P.vachanify(fs.readFile);
const write = P.vachanify(fs.writeFile);
function delayedCopy(file1,file2,delay)
{
return read(file1)
.delay(delay)
.then(data => write(file2,data));
}
delayedCopy("one.txt","two.txt",2000)
.then(
() => console.log("Success"),
err => console.log("Failure")
);
More details in API
then
, catch
and finally
are provided but along with those there are some other utility methods.
isFulfilled
, isPending
, isRejected
are methods provided for checking the internal state of the promise.
const { P } = require("vachan");
console.log(
P.resolve(10)
.isResolved()
);
console.log(
P.reject(new Error("Test!"))
.isRejected()
);
console.log(
new P()
.isPending()
);
tap
method allows you to tap on the promise chain without affecting the dataflow of the chain.
const { P } = require("vachan");
P.delay(10,200)
.tap(v => console.log("Tap: " + v))
.then(v => console.log("Then: " + v));
delay
method allows you to delay by a given amount of time the resolution of the next promise in the promise chain.
const { P } = require("vachan");
P.resolve(10)
.then(v => v+100)
.delay(500)
.then(v => console.log(v));
For coordinating multiple Promises the functions provided are all
, race
, any
, allSettled
and the instance methods provided are fork
and join
.
The below examples use the same premise but you can execute them to explore the consequence of using different coordinating techniques. These are static functions in the P class which facilitate coordination of Promises.
Waits for all the passed promises to get fulfilled and then resolves the returned promise.
const { P } = require("vachan");
P.all(
P.delay(10,100),
P.delay(20,200),
P.delay(30,300)
)
.then(v => console.log(v));
Waits for the first the promise to resolve, to resolve the returned promise.
const { P } = require("vachan");
P.race(
P.delay(10,100),
P.delay(20,200),
P.delay(30,300)
)
.then(v => console.log(v));
Similar to race but it waits for any one promise to get fulfilled or waits until all of the promises get rejected.
const { P } = require("vachan");
P.any(
P.delay(10,100),
P.delay(20,200),
P.delay(30,300)
)
.then(v => console.log(v));
Waits for all the promises to get resolved/settled (it can be in either state fulfilled or rejected) and then resolves the returned promise.
const { P } = require("vachan");
P.allSettled(
P.delay(10,100),
P.delay(20,200),
P.delay(30,300)
)
.then(v => console.log(v));
Examples below use instance methods fork
and join
of the P class which allows the consumer of the promise to handle multiple other promises along with the given promise without breaking the downward data propogation and the chaining abstraction.
This allows one promise to branch out into multiple promises and again aggregate into one promise while maintaining the fluent interface.
const { P } = require("vachan");
P.delay("hello",300)
.fork(v => v.length(), v => v + "bye", v => v.toUpperCase())
.then(v => console.log(v));
This allows multiple promises including the promise on which the method was invoked to be aggregated into one promise which waits for all to resolve while maintaining the fluent interface.
const { P } = require("vachan");
P.delay(10,100)
.join(
P.delay(20,200),
P.delay(30,400)
)
.then(v => console.log(v));
More details in API