Generating UUIDs with JavaScript Generators
I first heard about the term UUID in 2010 while coding with Microsoft Visual Basic, but UUIDs have been around a lot longer than that. Some developers refer to it as GUIDs. They both represent the same concept.
Globally Unique Identifier
GUID stands for Globally Unique Identifier these days developers prefer to call it UUID which means Universally Unique Identifier. These abbreviations refer to the same thing, but UUID is the term we shall be using going forward.
A UUID is a 128-bit label that is used to identify any resource or entity with a very high probability of uniqueness. A UUID is generated by following a standard or complex algorithm that combines different sources of randomness such as timestamps, MAC addresses, namespaces, names, or random numbers.
There are different flavors and formats of UUIDs. Each one depends on a specific algorithm and the representation used. The most common format is a string of 32 hexadecimal digits, separated by hyphens into five groups, such as 550e8400-e20b-a796–446655440000. The first group indicates the version of the UUID, and the last group denotes the flavor of the UUID.
Currently, there are five known versions of UUIDs and four variants defined by the RFC 4122 standard.
You may need to create a UUID in JavaScript if you want to have a unique and consistent way of identifying resources, such as files, objects, or components, across different systems or platforms. For example, if you are developing a web application that needs to store or sync data with a server or a database, you can use UUIDs as keys or identifiers for your data. This way, you can avoid conflicts or collisions with other data that may have the same name or ID. UUIDs play an indispensable role when generating random passwords, secure tokens, or unique identifiers are required.
UUIDs may be generated using different methods and algorithms or a specific library such as uuid. You can also use a specialized command line tool to generate one. Or you can write a concise JavaScript Generator function that generates a random UUID following the xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx pattern.
What are JavaScript Generators?
Let’s now beam our searchlights on Generators. These are a special type of function object in JavaScript that are capable of returning multiple (and in some cases continuous) values on demand.
In contrast, normal functions return single values or nothing. When invoked a normal function predictably executes the same code from beginning to the point where it encounters a return statement, and either returns a specified value or nothing. For example:
function doSomething(a, b){
let sum = a + b;
return sum;
}Generator functions are different. They are declared as follows:
function* doSomething(a, b){
return 'Hello Generator function!'
}or
function *doSomething(a, b){
return 'Hello Generator function!'
}The distinguishing element is the asterisk * operator that is appended to the end of the functionkeyword or prepended to the name of the function. Generator functions return generator objects not primitive values as normal functions do. Let’s see this in the code example below:
function* generatorFunction() {
return 'Hello Generator!'
}
const generatorFn = generatorFunction();
console.log(generatorFn)
//output:
generatorFunction {<suspended>}
__proto__: Generator
[[GeneratorLocation]]: VM272:1
[[GeneratorStatus]]: "suspended"
[[GeneratorFunction]]: ƒ* generatorFunction()
[[GeneratorReceiver]]: Window
[[Scopes]]: Scopes[3]The generator objects returned by Generator functions are sometimes called iterators. Iterator objects come with a next()method, a mechanism that moves the iterator cursor through a sequence of values. Therefore, the outputting code will be:
// Call the next method on the Generator object
console.log(generatorFn.next());This will render the following output:
//output:
{value: "Hello Generator!", done: true}What have we learned from the foregoing? We can see that the message returned by invoking next() is “Hello Generator!”, and the status of done is true. This indicates that the iterator has completed its run. From this moment the generator function’s status will change from suspended to closed. Invoking generatorFnagain will give you an updated information about the current state of the generator which will be revealed as follows:
//output:
generatorFunction {<closed>}Generator functions work better when used in combination with the yield operator. The yield operator gives generator functions the ability to pause code execution and return the current value when the next() is invoked on it. Let’s assume we create a generator function as follows:
// Create a generator function with multiple yields
function* generatorFunction() {
yield 'California'
yield 'Colorado'
yield 'Georgia'
return 'Indiana'
}
const generatorFn = generatorFunction()Therefore invoking the next() method on the generatorFn will cause the function to pause at each step while returning a value. The value of donewill remain false until the final value is returned: For example:
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
//output:
{value: "Mercury", done: false}
{value: "Venus", done: false}
{value: "Mars", done: false}
{value: "Jupiter", done: true}In fact it is not even necessary to use a returnstatement in a generator. Generators are self-aware of the last iteration and will return {value:undefined, done:true}. Every subsequent call to next() will have the same effect after a generator’s iterations are completed.
Get Terfa Binda’s stories in your inbox
Join Medium for free to get updates from this writer.
The yield operator gives Generators its powers, especially in situations where working with infinite data streams and collections is desired. We can demonstrate this use case by creating an infinite loop within a generator function, that is made to keep incrementing a number as follows:
// Define a generator function that increments by one
function* increment() {
let i = 0
while (true) {
yield i++
}
}
// Initiate the generator
const counter = increment();
//print in console
console.log(counter.next());
console.log(counter.next());
console.log(counter.next());
console.log(counter.next());
console.log(counter.next());
//output
{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }The function returns a chain of values in an infinite loop while the done property remains false, thus ensuring that the increment function never halts. Even though the while(true) code block appears to be caught in an unending loop, execution is paused after each yield and resumed only when the iterator’s next method is invoked in the console.log code. The stateful value of the local i variable remains unchanged between each call and is maintained.
You are completely safe when an infinite loop with generators because it gives you the power to pause and resume execution at any time. This is the innovativeness that generators bring to JavaScript; the awesome ability to pause and resume code execution in between calls. However, you must exercise caution when using the generator in combination with the spread or for..of on an infinite data stream, which can create an uncontrollable infinite loop that could eventually cause the environment to crash.
Generating GUIDs With JavaScript Generators
We can now combine the innovative use of a generator function in JavaScript with a nifty function that can give us an endless front-end based UUID generator as follows:
function *guidGenerator() {
while (true) {
const uuidv4 = () => {
// Generate a random number from 0 to 15
function randomDigit () {
return Math.floor (Math.random () * 16);
}
// Generate a random hex digit
function randomHex () {
return randomDigit ().toString (16);
}
// Generate a random segment of 4 hex digits
function randomSegment () {
return randomHex () + randomHex () + randomHex () + randomHex ();
}
// Generate a UUID following the 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' pattern
return randomSegment () + '-' + randomSegment () + '-4'
+ randomSegment ().substring (1, 3) + '-' + randomHex ()
+ randomSegment ().substring (1, 3) + '-' + randomSegment ()
+ randomSegment ();
}
yield uuidv4();
}
}
const getGuid = guidGenerator();
console.log(getGuid.next());
console.log(getGuid.next());
console.log(getGuid.next());This will give you the following output:
{ value: '4cec-6d60-490-c46-9d06f2c1', done: false }
{ value: '5c69-795f-421-a0e-82ef2cd0', done: false }
{ value: '497a-2065-4e3-bb4-d94f0dd0', done: false }To extract the value out of the object you can write your code as follows:
const getGuid = guidGenerator();
console.log(getGuid.next().value);
console.log(getGuid.next().value);
console.log(getGuid.next().value);
//output
bac4-3650-4af-10a-5836de95
9f71-f4f2-489-11f-965f03ef
c18f-d3cd-4a0-2c4-1458bdf4Don’t forget UUIDs are unique, so you will get a different output on your machine.
That concludes our lesson.








