Javascript Generators

Generator functions allow you to define an iterative algorithm by writing a single function whose execution is not continuous. Generator functions are written using the function* syntax. See Iterators and Generators: mdn

Our example generator creates an iterator representing an infinite stream of points, roughly simulating a stream of mouse positions.

function* genPoints() { const {floor, random} = Math let [x, y] = [0, 0] while (true) { yield {x, y} x += 20 - floor(20 * (random()+random())) y += 20 - floor(20 * (random()+random())) } }

Infinite streams risk infinite loops. We can construct another generator which limits the range of the stream.

function* take(n, iterator) { let result, i = 0; while (!(result = iterator.next()).done && i++ < n) { yield result.value; } }

Lets introduce a little asynchrony to more closely model a stream of mouse movements.

async function* timejitter(iterator) { const {floor, random} = Math for (let point of iterator) { yield point let ms = 5 + floor(5 * (random()+random())) await new Promise(r => setTimeout(r, ms)) } }

Lets use these tools to draw some lines.

We need something that knows how to convert a sequence of points into graphics instructions.

async function drawLine(ctx, line, color) { let prev = null for await (let {x, y} of line) { // knows iterators ctx.beginPath() ctx.strokeStyle = color ctx.lineWidth = 1 if (prev == null) { ctx.moveTo(x, y) } else { ctx.moveTo(prev.x, prev.y) ctx.lineTo(x, y) } prev = {x, y} ctx.stroke() } }

We need a canvas on which to draw.

let canvas = document.createElement("canvas") canvas.id = "canvas" canvas.style = "border: 1px solid black;" canvas.width = 380 canvas.height = 300 let ctx = canvas.getContext("2d") ctx.translate(190, 150) output.appendChild(canvas)

Lets create a few lines.

let redLine = timejitter(take(200, genPoints())) let blueLine = timejitter(take(200, genPoints())) let greenLine = timejitter(take(200, genPoints()))

Here we draw our lines.

async function main() { drawLine(ctx, redLine, "lightblue") drawLine(ctx, blueLine, "palegreen") drawLine(ctx, greenLine, "green") } main() null

In the frame below we can view the results.

//wiki.dbbs.co/assets/pages/js-snippet-template/basicjs.html HEIGHT 330