UNPKG

10.9 kBMarkdownView Raw
1<div align="center" style="text-align: center;">
2 <h1 style="border-bottom: none;">async-poll</h1>
3
4 <p>Advanced polling module with timeout and metrics collection</p>
5</div>
6
7<hr />
8
9<a href="https://www.buymeacoffee.com/RLmMhgXFb" target="_blank" rel="noopener noreferrer"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 20px !important;width: auto !important;" ></a>
10[![tippin.me][tippin-me-badge]][tippin-me-url]
11[![Follow me][follow-me-badge]][follow-me-url]
12
13[![Version][version-badge]][version-url]
14[![Node version][node-version-badge]][node-version-url]
15[![MIT License][mit-license-badge]][mit-license-url]
16
17[![Downloads][downloads-badge]][downloads-url]
18[![Total downloads][total-downloads-badge]][downloads-url]
19[![Packagephobia][packagephobia-badge]][packagephobia-url]
20[![Bundlephobia][bundlephobia-badge]][bundlephobia-url]
21
22[![CircleCI][circleci-badge]][circleci-url]
23[![Dependency Status][daviddm-badge]][daviddm-url]
24[![codecov][codecov-badge]][codecov-url]
25[![Coverage Status][coveralls-badge]][coveralls-url]
26
27[![codebeat badge][codebeat-badge]][codebeat-url]
28[![Codacy Badge][codacy-badge]][codacy-url]
29[![Code of Conduct][coc-badge]][coc-url]
30
31> Writing your own polling function can be difficult and hard to collect metrics about the polling. `asyncPoll` aims to solve those with modern JavaScript and advanced API. By leveraging `async...await`, asynchronous polling function has never been easier and [Performance Timing/ Timeline API][performance-timeline-api-url] is used to collect metrics about each polling in terms of the duration.
32>
33> 🛠 Please check if `Performance Timing/ Timeline API` is supported on your browser or Node.js environment.
34
35## Table of contents <!-- omit in toc -->
36
37- [Pre-requisites](#pre-requisites)
38- [Install](#install)
39- [Usage](#usage)
40 - [TypeScript or native ES modules](#typescript-or-native-es-modules)
41 - [Node.js](#nodejs)
42 - [Browser](#browser)
43 - [ES Modules](#es-modules)
44 - [IIFE](#iife)
45 - [Performance Timing/ Timeline API via `PerformanceObserver`](#performance-timing-timeline-api-via-performanceobserver)
46- [API Reference](#api-reference)
47 - [AsyncPollOptions](#asyncpolloptions)
48 - [asyncPoll\<T\>(fn, conditionFn[, options])](#asyncpolltfn-conditionfn-options)
49- [License](#license)
50
51## Pre-requisites
52
53- [Node.js][nodejs-url] >= 8.9.0
54- [NPM][npm-url] >= 5.5.1 ([NPM][npm-url] comes with [Node.js][nodejs-url] so there is no need to install separately.)
55
56## Install
57
58```sh
59# Install via NPM
60$ npm install --save async-poll
61```
62
63## Usage
64
65### TypeScript or native ES modules
66
67```ts
68interface NewsData {
69 data: {
70 news: object[];
71 status: number;
72 };
73}
74
75import asyncPoll from 'async-poll';
76
77/** Fetch news from a mock URL */
78const fn = async () => fetch('https://example.com/api/news').then(r => r.json());
79/** Keep polling until the more than 100 `news` are received or `status` returns `complete` */
80const conditionFn = (d: NewsData) => d.data.news.length > 100 || d.data.status === 'complete';
81/** Poll every 2 seconds */
82const interval = 2e3;
83/** Timeout after 30 seconds and returns end result */
84const timeout = 30e3;
85
86asyncPoll<NewsData>(fn, conditionFn, { interval, timeout })
87 .then(console.log)
88 .catch(console.error);
89```
90
91### Node.js
92
93```js
94const { asyncPoll } = require('async-poll');
95
96/** Fetch news from a mock URL */
97const fn = async () => fetch('https://example.com/api/news').then(r => r.json());
98/** Keep polling until the more than 100 `news` are received or `status` returns `complete` */
99const conditionFn = d => d.data.news.length > 100 || d.data.status === 'complete';
100/** Poll every 2 seconds */
101const interval = 2e3;
102/** Timeout after 30 seconds and returns end result */
103const timeout = 30e3;
104
105asyncPoll(fn, conditionFn, { interval, timeout })
106 .then(console.log)
107 .catch(console.error);
108```
109
110### Browser
111
112#### ES Modules
113
114```html
115<script type="module">
116 import { asyncPoll } from 'https://unpkg.com/async-poll@latest/dist/async-poll.js';
117
118 /** Fetch news from a mock URL */
119 const fn = async () => fetch('https://example.com/api/news').then(r => r.json());
120 /** Keep polling until the more than 100 `news` are received or `status` returns `complete` */
121 const conditionFn = d => d.data.news.length > 100 || d.data.status === 'complete';
122 /** Poll every 2 seconds */
123 const interval = 2e3;
124 /** Timeout after 30 seconds and returns end result */
125 const timeout = 30e3;
126
127 asyncPoll(fn, conditionFn, { interval, timeout })
128 .then(console.log)
129 .catch(console.error);
130</script>
131```
132
133#### IIFE
134
135```html
136<script src="https://unpkg.com/async-poll@latest/dist/async-poll.iife.js"></script>
137<script>
138 const { asyncPoll } = window.AsyncPoll;
139
140 /** Fetch news from a mock URL */
141 const fn = async () => fetch('https://example.com/api/news').then(r => r.json());
142 /** Keep polling until the more than 100 `news` are received or `status` returns `complete` */
143 const conditionFn = d => d.data.news.length > 100 || d.data.status === 'complete';
144 /** Poll every 2 seconds */
145 const interval = 2e3;
146 /** Timeout after 30 seconds and returns end result */
147 const timeout = 30e3;
148
149 asyncPoll(fn, conditionFn, { interval, timeout })
150 .then(console.log)
151 .catch(console.error);
152</script>
153```
154
155### Performance Timing/ Timeline API via `PerformanceObserver`
156
157Performance timing data can be obtained via the experimental [Performance Tming API][performance-timing-api-url] that has been added as of [Node.js 8.5.0][nodejs-url] or [Performance Timeline API][performance-timeline-api-url] on browsers.
158
159```ts
160/** For Node.js **only**, no import is required on browser. */
161import { PerformanceObserver } from 'perf_hooks';
162
163async function main() {
164 let measurements: Record<string, unknown> = {};
165 const perfObs = new PerformanceObserver((list) => {
166 for (const n of list.getEntries()) {
167 measurements[n.name] = n.duration;
168 }
169 });
170 perfObs.observe({ entryTypes: ['measure'] });
171 const d = await asyncPoll(fn, conditionFn, { interval, timeout });
172 perObs.disconnect();
173
174 return {
175 data: d,
176 measurements,
177 };
178}
179```
180
181## API Reference
182
183### AsyncPollOptions
184
185```ts
186interface AsyncPollOptions {
187 interval: number;
188 timeout: number;
189}
190```
191
192### asyncPoll\<T\>(fn, conditionFn[, options])
193
194- `fn` <[Function][function-mdn-url]> Function to execute for each polling happens.
195- `conditionFn` <[Function][function-mdn-url]> Function to check the condition before a subsequent polling takes place. The function should return a boolean. If `true`, the polling stops and returns with a value in the type of `T`.
196- `options` <[AsyncPollOptions][asyncpolloptions-url]> Polling options.
197 - `interval` <[number][number-mdn-url]> Polling interval.
198 - `timeout` <[number][number-mdn-url]> Timeout.
199- returns: <[Promise][promise-mdn-url]<`T`>> Promise which resolves with a value in the type of `T`.
200
201## License
202
203[MIT License](https://motss.mit-license.org/) © Rong Sen Ng (motss)
204
205<!-- References -->
206[typescript-url]: https://github.com/Microsoft/TypeScript
207[nodejs-url]: https://nodejs.org
208[npm-url]: https://www.npmjs.com
209[node-releases-url]: https://nodejs.org/en/download/releases
210[performance-timing-api-url]: https://nodejs.org/api/perf_hooks.html
211[performance-timeline-api-url]: https://developer.mozilla.org/en-US/docs/Web/API/Performance
212[asyncpolloptions-url]: #asyncpolloptions
213
214<!-- MDN -->
215[array-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
216[boolean-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
217[function-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
218[map-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
219[number-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
220[object-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
221[promise-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
222[regexp-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
223[set-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
224[string-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
225
226<!-- Badges -->
227[tippin-me-badge]: https://badgen.net/badge/%E2%9A%A1%EF%B8%8Ftippin.me/@igarshmyb/F0918E
228[follow-me-badge]: https://flat.badgen.net/twitter/follow/igarshmyb?icon=twitter
229
230[version-badge]: https://flat.badgen.net/npm/v/async-poll/latest?icon=npm
231[node-version-badge]: https://flat.badgen.net/npm/node/async-poll
232[mit-license-badge]: https://flat.badgen.net/npm/license/async-poll
233
234[downloads-badge]: https://flat.badgen.net/npm/dm/async-poll
235[total-downloads-badge]: https://flat.badgen.net/npm/dt/async-poll?label=total%20downloads
236[packagephobia-badge]: https://flat.badgen.net/packagephobia/install/async-poll
237[bundlephobia-badge]: https://flat.badgen.net/bundlephobia/minzip/async-poll
238
239[circleci-badge]: https://flat.badgen.net/circleci/github/motss/async-poll?icon=circleci
240[daviddm-badge]: https://flat.badgen.net/david/dep/motss/async-poll
241[codecov-badge]: https://flat.badgen.net/codecov/c/github/motss/async-poll?label=codecov&icon=codecov
242[coveralls-badge]: https://flat.badgen.net/coveralls/c/github/motss/async-poll?label=coveralls
243
244[codebeat-badge]: https://codebeat.co/badges/56458b75-7d18-4a52-b3eb-b29f5367e244
245[codacy-badge]: https://api.codacy.com/project/badge/Grade/fdcab22d5b26401486e89d0ed1124171
246[coc-badge]: https://flat.badgen.net/badge/code%20of/conduct/pink
247
248<!-- Links -->
249[tippin-me-url]: https://tippin.me/@igarshmyb
250[follow-me-url]: https://twitter.com/igarshmyb?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=motss/async-poll
251
252[version-url]: https://www.npmjs.com/package/async-poll
253[node-version-url]: https://nodejs.org/en/download
254[mit-license-url]: https://github.com/motss/async-poll/blob/master/LICENSE
255
256[downloads-url]: http://www.npmtrends.com/async-poll
257[packagephobia-url]: https://packagephobia.now.sh/result?p=async-poll
258[bundlephobia-url]: https://bundlephobia.com/result?p=async-poll
259
260[circleci-url]: https://circleci.com/gh/motss/async-poll/tree/master
261[daviddm-url]: https://david-dm.org/motss/async-poll
262[codecov-url]: https://codecov.io/gh/motss/async-poll
263[coveralls-url]: https://coveralls.io/github/motss/async-poll?branch=master
264
265[codebeat-url]: https://codebeat.co/projects/github-com-motss-async-poll-master
266[codacy-url]: https://www.codacy.com/app/motss/async-poll?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=motss/async-poll&amp;utm_campaign=Badge_Grade
267[coc-url]: https://github.com/motss/async-poll/blob/master/CODE_OF_CONDUCT.md