GithubHelp home page GithubHelp logo

vahagnni / timers Goto Github PK

View Code? Open in Web Editor NEW

This project forked from webosorg/timers

0.0 1.0 0.0 204 KB

Abstraction layer on setTimeout and setInterval, implementation of setImmediate.

JavaScript 100.00%

timers's Introduction

@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

timers's People

Contributors

suren-atoyan avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.