Categories
JavaScript JavaScript Basics

Add a Timer to Run Code Between Specified Time Intervals With JavaScript

Adding a timer is easy with JavaScript. There’re 2 methods for adding a timer into our JavaScript app. One is the setTimeout function. The other is the setInterval function.

Thr setInterval function lets us run code after a given delay in milliseconds repeatedly. It’s queued to be run after the given amount of delay time and then it’ll run the callback we pass in into the main thread.

For instance, we can use it as follows:

setInterval(() => console.log('hi'), 1000);

In the code above, we passed in a callback function as the first argument of the time setInterval function and a 1000 ms interval as the second argument.

Then we should see 'hi' logged in the console log output after every second.

We can also pass in arguments to the callback by passing in more arguments after the second argument. They can be accessed in the callback in the same order.

For instance, we can do that as follows:

setInterval((greeting) => console.log(greeting), 1000, 'hi');

In the code above, we passed 'hi' as the 3rd argument of setInterval, which will let us access the argument from the greeting parameter.

Therefore, we’ll see 'hi' logged in the console log output since greeting is 'hi'.

setInterval also takes a string instead of a callback as the first argument, where the string has the code that a callback normally has.

However, this prevents performance optimizations from being done and also presents security issues since attackers can potentially inject their own code as a string into the setInterval if we aren’t careful.

If we don’t need the timer any more, we can cancel the timer by calling the clearInterval function which takes the timer ID object that’s returned by setInterval.

For instance, we can do that as follows:

const timer = setInterval((greeting) => console.log(greeting), 1000, 'hi');
clearInterval(timer);

Since we called clearInterval immediately after calling setInterval, the callback won’t be called since we disposed of our timer with clearInterval.

Categories
JavaScript JavaScript Basics

Add a Timer With JavaScript

Adding a timer is easy with JavaScript. There’re 2 methods for adding a timer into our JavaScript app. One is the setTimeout function. The other is the setInterval function.

Thr setTimeout function lets us run code after a given delay in milliseconds. It’s queue to be run after the given amount of delay time and then it’ll run the callback we pass in into the main thread.

For instance, we can use it as follows:

setTimeout(() => console.log('hi'), 1000);

In the code above, we passed in a callback function as the first argument of the time setTimeout function and a 1000 ms delay as the second argument.

Then we should see 'hi' logged in the console log output after 1 second.

We can also pass in arguments to the callback by passing in more arguments after the second argument. They can be accessed in the callback in the same order.

For instance, we can do that as follows:

setTimeout((greeting) => console.log(greeting), 1000, 'hi');

In the code above, we passed 'hi' as the 3rd argument of setTimeout, which will let us access the argument from the greeting parameter.

Therefore, we’ll see 'hi' logged in the console log output since greeting is 'hi'.

setTimeout also takes a string instead of a callback as the first argument, where the string has the code that a callback normally has.

However, this prevents performance optimizations from being done and also presents security issues since attackers can potentially inject their own code as a string into the setTimeout if we aren’t careful.

If we don’t need the timer any more, we can cancel the timer by calling the clearTimeout function which takes the timer ID object that’s returned by setTimeout.

For instance, we can do that as follows:

const timer = setTimeout((greeting) => console.log(greeting), 1000, 'hi');
clearTimeout(timer);

Since we called clearTimeout immediately after calling setTimeout, the callback won’t be called since we disposed of our timer with clearTimeout.

Categories
JavaScript JavaScript Basics

Why it’s time to use the async-await in JavaScript?

Asynchronous code is a regular part of JavaScript. As web apps get more complex, there’ll be more need for asynchronous code since JavaScript is single-threaded, and asynchronous code prevents the blocking of the main thread.

In this article, we’ll look at why async and await is the way to go for writing asynchronous code.

The Old Way to Write Promise Code

Before we look at async and await, we have to look at what it’s like in the old days.

In the olden days, we chain promises by writing something like the following:

Promise.resolve(1)  
  .then(val => Promise.resolve(2))  
  .then(val => Promise.resolve(3))  
  .then(val => Promise.resolve(4))  
  .then(val => Promise.resolve(5))  
  .then(val => Promise.resolve(6))

As we can see, we have to call then a lot and in each then call, we have to pass in a callback function to return the next promise. This is a pain because it’s very long-winded. If we want to do something like gathering the resolved values from each promise, then the code gets even longer.

For example, to gather the resolved values into an array, we have to write something like:

let vals = [];  
Promise.resolve(1)  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(2)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(3)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(4)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(5)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(6)  
  })  
  .then(val => {  
    vals.push(val);  
    console.log(vals)  
  });

Then we get [1, 2, 3, 4, 5, 6] as the value of vals.

As we can see, the number of lines of code exploded compared to the first example.

There’s lots of repetition and takes up lots of space in a file.

To deal with this, it’s time to move to the present with the async-await syntax for chaining promises.

Async and Await

To clean up the code in the example above, we can use async and await to do this.

We start a function declaration with async and we use the await keyword inside. await does the same thing as the then callbacks. It takes the resolved value of the promise and lets us do stuff with it.

With async and await, we can turn:

let vals = [];  
Promise.resolve(1)  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(2)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(3)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(4)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(5)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(6)  
  })  
  .then(val => {  
    vals.push(val);  
    console.log(vals)  
  });

into:

(async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  console.log(vals);  
})();

The await in the code above indicates that the code to the right of it returns a promise, and it’ll wait for the promise to be fulfilled until it moves on to the next one. Also, the resolved value can be assigned with the = and the variable or constant to the left of it.

The values can be gathered into an array at the end of the function and we can log it.

Even though this looks like synchronous code, async function can only return promises, so if we return vals, we’ll get a promise that resolves to the value of vals.

This means that:

const getVals = () => {  
  let vals = [];  
  Promise.resolve(1)  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(2)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(3)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(4)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(5)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(6)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(vals);  
    });  
}

is the same as:

const getValsAsyncAwait = async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  return vals;  
};

We can use await on both and see what we get.

This block:

const getVals = () => {  
  let vals = [];  
  return Promise.resolve(1)  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(2)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(3)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(4)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(5)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(6)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(vals);  
    });  
}

(async () => {  
  const values = await getVals();  
  console.log(values);  
})()

gets us [1, 2, 3, 4, 5, 6] from the console.log.

And:

const getValsAsyncAwait = async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  return vals;  
};

(async () => {  
  const values = await getValsAsyncAwait();  
  console.log(values);  
})()

also gets us [1, 2, 3, 4, 5, 6] from the console.log. So they do exactly the same thing, just with much fewer lines of code.

Catching Errors

In the olden days we catch errors with the catch and the callback passed into it.

For example, we write something like:

Promise.resolve(1)  
  .then(val => console.log(val))  
  .catch(err => console.log(err));

Now we can use try...catch with async and await:

(async () => {  
  try {  
    const val = await Promise.resolve(1);  
  } catch (err) {  
    console.log(err);  
  }  
})();

This doesn’t save much space, but this may still come in handy in case of errors.

As we can see, async and await make code for chaining promises so much shorter. It’s been available since 2017, so it’s supported by most modern browsers. The time to use this to clean up our code is definitely now.

Categories
JavaScript JavaScript Basics

Scheduling Code Execution with JavaScript setTimeout and setInterval Functions

JavaScript has functions for running functions at a specified schedule time or interval. They’re the setTimeout and setInterval functions respectively.

setTimeout

setTimeout lets us run code after a specified time from the setTimeout function is called. It takes 2 arguments. The first is a callback function with code that we want to run. The second argument is the time in which the code in the callback function runs relative to the time that this function is called. This argument is a number in milliseconds.

We can use it as follows:

setTimeout(() => {  
  console.log('Hi');  
}, 3000)

The code above will log 'Hi' after 3 seconds, which is 3000 milliseconds.

We can also pass in a function reference or variable as follows:

function hi() {  
  console.log('Hi');  
}

setTimeout(hi, 3000)

Or we can write:

const hi = () => {  
  console.log('Hi');  
}

setTimeout(hi, 3000)

Notice that we just pass in the function name. This is because the function is to be run later, not immediately. Therefore, we want to pass in a function reference instead of calling it in the code.

We can pass in arguments to the callback function by specifying additional arguments after the second one. For example, we can write:

setTimeout((name, age) => {  
  console.log(`Hi ${name}. Your age is ${age}.`)  
}, 3000, 'Joe', 20);

After we run the code above, we should see 'Hi Joe. Your age is 20.’ since we passed in 'Joe' for name and 20 for age .

The setTimeout function returns an ID object which can be used to cancel the setTimeout operation with the clearTimeout function. We can use it as follows:

let timerId = setTimeout(() => {  
  console.log('Hi');  
}, 3000)

clearTimeout(timerId);

If we run the code above, we’ll see nothing since we cancelled the operation with the clearTimeout function.

Repeated setTimeout

We can use setTimeout like setInterval by nesting the callback function inside itself. For example to log 'Hi' every 3 seconds, we can write:

setTimeout(function hi() {  
  console.log('Hi');  
  setTimeout(hi, 3000);  
}, 3000)

Then we can cancel the repeated operations by:

let timerId;  
timerId = setTimeout(function hi() {  
  console.log('Hi');  
  timerId = setTimeout(hi, 3000);  
}, 3000)

clearTimeout(timerId);

The callback functions’ execution time is counted in the delay that we pass into the second argument, so the actual interval between the function runs is less than the delay we specified.

Zero Delay setTimeout

To run code immediately after the script is executed, we can specify 0 for the delay in the setTimeout function. For example, we can write:

console.log('1');  
setTimeout(() => {  
  console.log('3');  
})  
console.log('2');

Then we see that 1, 2 and 3 are logged in that order. This is because all the synchronous code is run first. Then the asynchronous code in the setTimeout ‘s callback function is run.

setInterval

The setInterval function lets us run code repeatedly at a specified time interval.

The arguments are the same as setTimeout .

We can use it as follows:

setInterval(() => {  
  console.log('Hi');  
}, 3000)

When we run the code above, we see the word 'Hi' logged every 3 seconds.

Like setTimeout , there’s a function to cancel the setInterval operation. There’s a clearTimeout function to cancel it.

setInterval returns an ID object which we can pass into the clearInterval method to cancel the operation.

For example, we can write:

let timerId = setInterval(() => {  
  console.log('Hi');  
}, 3000)

clearTimeout(timerId);

If we run the code above, we see that nothing is logged since the setInterval operation was cancelled immediately after it’s initiated.

We can pass in arguments to the callback function by specifying additional arguments after the second one. For example, we can write:

setInterval((name, age) => {  
  console.log(`Hi ${name}. Your age is ${age}.`)  
}, 3000, 'Joe', 20);

After we run the code above, we should see 'Hi Joe. Your age is 20.’ since we passed in 'Joe' for name and 20 for age.

Value of this

The value of this should be the window object and not undefined by default, even in strict mode.

For example, if we write:

setInterval(() => {  
  console.log(this)  
}, 3000);

We should get the window object logged every 3 seconds.

The setTimeout and setInterval functions are timer functions that let us run code that we want to schedule for a specified time or an interval respectively.

We do this by passing in a callback function which runs the code we want to delay or run repeatedly. Then we specify the delay or interval in milliseconds.

To pass in arguments to the callback function, we can specify additional arguments after the second argument in both functions.

The timer isn’t always exactly because of CPU issues like it being overloaded, or lots of background processes are running, or the CPU is throttled.

Categories
JavaScript JavaScript Basics

The Ultimate Guide for Manipulating Numbers in JavaScript

Rounding Numbers

JavaScript has multiple ways to round a number. Some choices are Math.round, number.toFixed, and number.toPrecision. You can also write your own function to round a number up or down to the nearest increment.


Math.round

Math.round rounds a number to the nearest integer. If the decimal part of the number is less than 0.5, it is rounded down. Otherwise, if the decimal part of the number is 0.5 or higher it will be rounded up.

The function returns the rounded number as the value.

For example:

Math.round(12.5); // 13  
Math.round(12.49); // 12

Number.toFixed

You can set the number of digits that appears after the decimal place with the toFixed function. The function returns the string representation of the number as the value.

It can be used like this:

const a = 12.8888888888;  
const b = a.toFixed(2); // 12.88

Number.toPrecision

Number.toPrecision is similar to toFixed.

It returns the string representation of a number but you can round it to the specified number of significant digits, which you can specify or let it automatically round to the correct number of significant digits.

const a = 12.8888888888;  
const b = a.toPrecision(2); // 13, since 2 significant digits is specified  
const c = a.toPrecision(); // 12.8888888888, since all digits are significant in the original number

Round to the Nearest Increment

You can round to the nearest increment, up or down, as you specify:

const roundNumberUp = (num, increment) => {   
  return Math.ceil(num / increment) * increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is it takes the original number, divides it by the increment you want to round up to, then takes the ceiling of that, then multiplies by the increment. This means that the number should always round up.

Similarly, you can round down to the nearest increment with floor.

const roundNumberUp = (num, increment) => {   
  return Math.floor(num / increment) * increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is it takes the original number, divides it by the increment you want to round up to, then takes the floor of that, then multiplies by the increment. This means the number should always round down.


Exponentiation

There are multiple ways to compute exponents with JavaScript.

The newest way is the exponentiation operator **, available with ES2016 or higher.

For example, we can do this:

const a = 2 ** 3; // 8

It is right associative, so a ** b ** c is equal to a ** (b ** c). This works with all exponents.

For example:

const a = 2 ** (3 ** 4);  
const b = 2 ** 3 ** 4;  
a == b // true, both are 2.4178516392292583e+24

Detailed browser compatibility is available on the Mozilla website.

We can also use the Math.pow function, like this:

const a = Math.pow(2,3) // 8

It takes two arguments, the first is the base and the second is the exponent. Math.pow works with all exponents.

Math.pow is compatible with all recent browsers.


Rounding Numbers

JavaScript has multiple ways to round a number. Some choices are: Math.round, number.toFixed, and number.toPrecision. You can also write your own function to round a number up or down to the nearest increment.


Math.round

Math.round rounds a number to the nearest integer.

If the decimal part of the number is less than 0.5, it is rounded down. Otherwise, if the decimal part of the number is 0.5 or higher, it will be rounded up. The function returns the rounded number as the value.

For example:

Math.round(12.5); // 13  
Math.round(12.49); // 12

Number.toFixed

You can set the number of digits that appear after the decimal place withthe toFixed function. The function returns the string representation of the number as the value. It can be used like this:

const a = 12.8888888888;  
const b = a.toFixed(2); // 12.88

Number.toPrecision

Number.toPrecision is similar to toFixed.

It returns the string representation of a number but you can round it to the specified number of significant digits, which you can specify or let it automatically round to the correct number of significant digits.

const a = 12.8888888888;  
const b = a.toPrecision(2); // 13, since 2 significant digits is specified  
const c = a.toPrecision(); // 12.8888888888, since all digits are significant in the original number

Round to the Nearest Increment

You can round to the nearest increment up or down you specify:

const roundNumberUp = (num, increment) => {   
  return Math.ceil(num / increment) * increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is take the original number, divide by the increment you want to round up to, then take the ceiling of that, then multiply by the increment. This means the number should always round up.

Similarly, you can round down to the nearest increment with floor.

const roundNumberUp = (num, increment) => {   
  return Math.floor(num / increment) * increment;  
}  
console.log(roundNumberUp(12.2, 0.5)) // 12.5

What this does is take the original number, divide by the increment you want to round up to, then take the floor of that, then multiply by the increment. This means the number should always round down.