2.4 KiB
Generators
Generator functions can be used to yield and use the event loop to your liking.
Meaning that when having to do with heavy functions or large datasets, we can open the event loop by yielding in the loop. This makes the UI i.e render between heavy functions. Combine it with setTimeout(function, 0) for great use. To unblock the UI we await a MacroTask (useTimeout()). This forces the execution out of the call stack and allows the browser to paint before continuing.
Generator functions are great for use when streaming data from a source. This could be token response from an AI.
Great for handling large datasets i.e a 10gb csv file where we can yield each line, which opens up the thread and the event loop. This is called Lazy Evaluation, which means we only keep one line open in memory at a time instead of loading all of the 10gb. This is great for performance.
Frontend wise, it can be used in pagination or when fetching from many URLs with numbered params for example. This could allow for smooth animations when fetching as well.
Below is an example of mocking and processing a datastream using a generator function.
export async function* mockAIStream() {
const response = "this is a mock response and a lot of text text text, and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,,";
const tokens = response.split(" ");
for (const token of tokens) {
// Simulate the delay. Netowrk latency or anything. Process time
const delay = Math.floor(Math.random() * 300) + 100; // Random delay between 100ms and 400ms
await new Promise((resolve) => setTimeout(resolve, delay));
// Yield the token. Pass it to the caller.
yield token + " ";
}
}