Christopher Pitt
Writer and coder, working at ringier.co.za
const items = ["apple", "orange", "strawberry"]; for (let i = 0; i < items.length; i++) { console.log(items[i]); }
*unless you're changing the array between look-ups
const Iterator = function () { let i = 0; const items = ["apple", "orange", "strawberry"]; const done = function () { return i >= items.length; }; return { done, next: function () { i++; return items[i - 1]; } }; }; const iterator = Iterator(); while (!iterator.done()) { console.log(iterator.next()); }
function* (items) { for (let i = 0; i < items.length; i++) { yield items[i]; } }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
const Generator = function () { const items = ["apple", "orange", "strawberry"]; return { [Symbol.iterator]: function* () { for (let i = 0; i < items.length; i++) { yield items[i]; } } }; }; const generator = Generator(); for (const next of generator) { console.log(next); }
class Task { constructor(generator) { this.generator = generator(); } tick() { return this.generator.next(); } }
class Runner { tasks = []; add(task) { this.tasks.push(task); } tick() { const task = this.tasks.shift(); if (!task) { return false; } if (!task.tick().done) { this.add(task); } return this.tasks.length; } }
const runner = new Runner(); runner.add( new Task(function* () { for (let i = 0; i < 5; i++) { console.log(`first task is ${i}`); yield; } }) ); runner.add( new Task(function* () { for (let i = 0; i < 3; i++) { console.log(`second task is ${i}`); yield; } }) ); while (runner.tick());
[Log] first task is 0 [Log] second task is 0 [Log] first task is 1 [Log] second task is 1 [Log] first task is 2 [Log] second task is 2 [Log] first task is 3 [Log] first task is 4
const ayyysync = function (generatorFactory) { return generatorFactory(); }; const ayyywait = function (generatorInstance) { let previous = undefined; while (true) { const next = generatorInstance.next(); if (!next.done) { previous = next.value; } else { break; } } return previous; };
const task = function () { return ayyysync(function* () { for (let i = 0; i < 5; i++) { console.log(`third task is ${i}`); yield "done"; } }); }; const result = ayyywait(task());
const task = function () { return ayyysync(function* () { // ... }); }; const out = ayyywait(task()); vs. const task = async function() { // ... }; const out = await task();
const task = function () { return ayyysync(function* () { // ... }); }; const out = ayyywait(task()); vs. const task = async function() { // ... }; const out = await task();
const [_, changeSets] = await Promise.all([ clearCache(), getChangeSets({ state: published }), ]) await cacheChangeSets(changeSets)
const sleep = function (ms) { return new Promise(function (resolve) { setTimeout(function () { resolve(`slept for ${ms}`); }, ms); }); }; const task = async function () { console.log("starting..."); const result = await sleep(100); console.log(`resulted in ${result}`); return sleep(200); };
const task = Awaitable([ function (__previous, __context) { console.log("starting..."); }, sleep(100), function (__previous, __context) { __context["result"] = __previous; console.log(`resulted in ${__context["result"]}`); }, sleep(200) ]);
// in the background... let tasks = []; setInterval(function () { let remaining = []; for (const task in tasks) { if (task.awaiting && task.awaiting.isResolved) { task.resume(task.awaiting.value); } if (!task.isResolved) { remaining.push(task); } } tasks = remaining; }, 0);
*event loop, interrupts, network, fs, threading, promises
*reactphp, amphp
use Psr\Http\Message\ServerRequestInterface; use React\Http\HttpServer; use React\Http\Message\Response; use React\Socket\SocketServer; $http = new HttpServer(function(ServerRequestInterface $request) { return new Response( 200, ["Content-Type" => "text/plain"], "Hello world\n", ); }); $socket = new SocketServer("127.0.0.1:8080"); $http->listen($socket);
use Amp\Http\Server\HttpServer; use Amp\Http\Server\RequestHandler\CallableRequestHandler; use Amp\Http\Server\Response; use Amp\Http\Status; use Amp\Loop; use Amp\Socket\Server; Loop::run(function() { $server = new HttpServer( [Server::listen("127.0.0.1:8080")], new CallableRequestHandler(function() { return new Response( Status::OK, ["content-type" => "text/plain"], "Hello world\n", ); }) ); yield $server->start(); });
$task = async function($client) { $this->prepare($client); await $update($client); };
$task = [ ($update = $update ?? null), "fn" => function ($client) use (&$update): \Amp\Promise { return \Amp\call(function () use (&$update) { $this->prepare($client); yield $update($client); }); } ]["fn"];
slides.com/assertchris/inventing-async-await-september-2021
By Christopher Pitt