33
loading...
This website collects cookies to deliver better user experience
Promises
that will make sure our loading indicator will disappear only when the last unresolved Promise
gets resolved. We'll also make sure that the function is reusable so that it can be used with any project and with any progress loading indicator plugin.createLoader.ts
export const createLoader = (options: {
start: () => void;
end: () => void;
inc?: () => void;
slackTime?: number;
}) => {
const promises: Promise<unknown>[] = [];
const opts = {
...{
inc: () => {},
slackTime: 0,
},
...options,
};
const load = <T>(promise: Promise<T> | (() => Promise<T>)) => {
const p = typeof promise === 'function' ? promise() : promise;
!promises.length && opts.start();
promises.push(p);
p.finally(() => {
setTimeout(() => {
promises.pop();
!promises.length ? opts.end() : opts.inc();
}, opts.slackTime);
});
return p;
};
return { load };
};
Promise
is resolved.slackTime
that will be used as a delay to wait until the last Promise
is resolved. This is useful in cases that we have e.g an API call that starts shortly after another call has just finished, causing a "flickering" effect in our loader.load
method which will accept a Promise
or a function that returns a Promise
. Instead of firing our async
functions directly, we'll pass them through our load
function instead. Our loader then will make sure that the loading progress ends when the last of the Promises
is resolved.Option | Description | Type | Default |
---|---|---|---|
start |
A function to execute on loading start, this is where we start our progress loader | function |
undefined |
end |
A function to execute when loading ends, this is where we stop our progress loader | function |
undefined |
inc |
An optional function to execute when a promise resolves (valid for all promises except the last one). We can use this function to increment our loading progress. | function |
() => {} |
slackTime |
Time in ms to wait until last promise is resolved as to enable multiple operations in a sequence without re-triggering a loader progress start |
Number |
0 |
loader.ts
import NProgress from 'nprogress';
import { createLoader } from './createLoader';
NProgress.configure({
minimum: 0.35,
speed: 300,
});
const start = () => {
NProgress.start();
};
const end = () => {
NProgress.done();
};
const inc = () => {
NProgress.inc(0.05);
};
const loader = createLoader({ start, end, slackTime: 350, inc });
export const { load } = loader;
NProgress
instance and setup a new loader that will start, end, or increment the nprogress
progress bar depending on the Promises
' state.Promises
into the load
function and our loader will take care of the rest. Here's an example using axios
that dispatches two requests so that they get registered in our loader.import { load } from './loader';
import axios from 'axios';
const res1 = load(axios.get(`https://jsonplaceholder.typicode.com/todos`));
const res2 = load(axios.get(`https://jsonplaceholder.typicode.com/todos/1`));
npm run dev
on the console.npm install promise-loading-handler