npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@webos/timers

v1.0.8

Published

Abstraction layer on setTimeout and setInterval, implementation of setImmediate.

Downloads

11

Readme

@webos/timers

(a histogram of downloads)

Synopsys

Abstraction layer on setTimeout and setInterval, implementation of setImmediate.

Introduction

There are six functions in this library.

sleep

(milliseconds: optional (default 0)) -> Reusable Lazy Promise

Usage

sleep(3000).then(_ => console.log('Log ::: After ~3000 milliseconds'));
const sleep_five_seconds = sleep(5000);
sleep_five_seconds.then(_ => console.log('Log ::: After ~5 seconds'));
//
//
sleep_five_seconds.then(...) // it can be reused many times

sleep uses setTimeout wrapped with reusable lazy promise ( when 0 or nothing is passed, it calls setImmediate instead of setTimeout);

nextTick

() -> Reusable Lazy Promise

Usage

nextTick().then(_ => console.log('Log ::: immediately'));
const next_tick = nextTick();
next_tick.then(_ => console.log('Log ::: immediately'));
//
//
next_tick.then(...); // it can be reused many times

nextTick uses setImmediate wrapped with reusable lazy promise.

every

(fn: required, milliseconds: optional (default 0), iterations: optional (default Infinity)) -> Reusable Lazy Promise

Usage

every(_ => console.log('Log ::: every ~500 milliseconds'), 500, 20).then(_ => console.log('Log ::: I have finished'));
const log_every_ten_milliseconds = every(_ => console.log('Log ::: every ~10 milliseconds'), 500, 4);
log_every_ten_milliseconds.run();
// Log ::: every ~10 milliseconds
// Log ::: every ~10 milliseconds
log_every_ten_milliseconds.stop();
log_every_ten_milliseconds.run();
// Log ::: every ~10 milliseconds
// Log ::: every ~10 milliseconds

every uses setInterval wrapped with reusable lazy promise. So, it means that every next call of fn will be after inputted time. ( When execution time of fn is not bigger than inputted time ). For example, let's consider that we have an application of every like this.

every(fn, 500, 4).then(...)

And, let's imagine that the execution time of fn is ~100 milliseconds. In this case it will work like this.

alt every

As we see, each next function will be called after 400 milliseconds from the end of the previous function. If you want to call every next function after inputted time plus execution time of function you can use loopDelayBetween instead of every.

loopDelayBetween

(fn: required, milliseconds: optional (default 0), iterations: optional (default Infinity)) -> Reusable Lazy Promise

Usage

loopDelayBetween(_ => console.log('Log ::: every ~500 milliseconds'), 500, 20).then(_ => console.log('Log ::: I have finished'));
const log_every_ten_milliseconds = every(_ => console.log('Log ::: every ~10 milliseconds'), 500, 4);
log_every_ten_milliseconds.run();
// Log ::: every ~10 milliseconds
// Log ::: every ~10 milliseconds
log_every_ten_milliseconds.stop();
log_every_ten_milliseconds.run();
// Log ::: every ~10 milliseconds
// Log ::: every ~10 milliseconds

Unlike every, loopDelayBetween uses recursive setTimeout or setImmediate ( when inputted time is 0 ) instead of setInterval. So, it will call every next function after previous function execution time plus inputted time. For example, suppose that we have an application of loopDelayBetween like this.

loopDelayBetween(fn, 500, 4).then(...)

And, let's imagine that execution time of fn is ~100 milliseconds. In this case it will work like this.

alt loopDelayBetween

setImmediate

MDN - This method is used to break up long running operations and run a callback function immediately after the browser has completed other operations such as events and display updates.

The setImmediate problem is that it's not part of any specification and is not supported by many browsers.

MDN

alt setImmediate_

setImmediate is similar to setTimeout(..., 0). But setTimeout have minimum timeout (~4ms). It means that when we call setTimeout(..., 0) it will work after ~4ms.

MDN

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms. In fact, 4ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the minimum timeout value for nested timeouts was 10 ms. In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks. To implement a 0 ms timeout in a modern browser, you can use window.postMessage() as described here. Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer.

There are some implementations of this, like setZeroTimeout or setImmediate. The best polyfill of setImmediate is this polyfill. They use postMessage, MessageChannel, even "script onreadystatechange" for reaching maximum support in old browsers.

In this library, the implementation of setImmediate uses Promise.resolve(). It's the fastest way, but writing setImmediate polyfill by using Promise.resolve() has one problem. It's the following: Promise polyfill uses setImmediate inside, if it exists.

promise-polyfill

alt promise-polyfill

So, if we write setImmediate polyfill without using checkings, cyclic calls will occur. For avoiding this the implementation of setImmediate in this library checks if the browser supports native Promise, If so, it uses Promise.resolve(), otherwise uses setTimeOut(..., 0). Can I use... says that ~90% of all browsers support native Promise. So, in nearly 90% of all browsers this implementation of setImmediate will work much more faster than any other implementation. But, of course, in 10% of browsers setTimeout(..., 0) will work.

====

(fn: required) -> timerID

Usage

const timerID = setImmediate(fn)

clearImmediate

(timerID) -> Boolean

Usage

const timerID = setImmediate(fn);

clearImmediate(timerID);

License

MIT