UNPKG

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