James Hunter
@cccc00
::console.log
console.log.bind(console)
Promise.resolve(4)
.then(::console.log)
// 4Works Like
=
function bob (x) {
return x + x
}
function bob (x) {
return x + x
}
bob is reliable
function bob (x) {
return x + x
}
bob is predictable
function bob (x) {
return x + x
}
bob always answers arguments the same way
function bob (x) {
return x + x
}
bob is a singular synchronous operation
function steve (x) {
const y = inc()
return x + y
}
function steve (x) {
const y = inc()
return x + y
}
steve is nice
function steve (x) {
const y = inc()
return x + y
}
steve has a second job on the side
function steve (x) {
const y = inc()
return x + y
}
steves second job blocks him from
doing his actual job
function steve (x) {
const y = inc()
return x + y
}
steve is a singular synchronous operation
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam.
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam...
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam replies right away
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam is all over the place
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam likes rules, not tools
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
cam is a singular asynchronous operation
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
pat (like cam) replies right away
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
pat looks simple
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
pat thinks differently than you
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
pat is a singular asynchronous operation
get off the stage
But in all seriousness
much synchronous
very asynchronous
such promises
many callbacks
such synchronous
much asynchronous
many promises
very callbacks
very synchronous
many asynchronous
much promises
such callbacks
function steve (x) {
const y = inc()
return x + y
}
good ol' steve
function steve (x) {
const y = inc()
return x + y
}
I want to write my asynchronous code like this
function steve (x) {
const y = inc()
return x + y
}
I want a super steve
function steve (x) {
const y = inc()
return x + y
}
I want a super steve
– Marvel
function steve (x) {
const y = inc()
return x + y
}
import { coroutine } from "bluebird"
let superSteve = coroutine(function * (x) {
const y = yield inc()
return x + y
})Turns out pretty close
function steve (x) {
const y = inc()
return x + y
}
import { coroutine } from "bluebird"
let superSteve = coroutine(function * (x) {
const y = yield inc()
return x + y
})Turns out pretty close
let steve = function (x) {
const y = inc()
return x + y
}
import { coroutine } from "bluebird"
let superSteve = coroutine(function * (x) {
const y = yield inc()
return x + y
})well....
are synchronous sequences, where the consumer pulls data at the rate they desire
– Domenic Denicola
let iter = ["a","b","c"].entries()
iter.next() // {value: [0,"a"], done: false}
iter.next() // {value: [1,"b"], done: false}
iter.next() // {value: [2,"c"], done: false}
iter.next() // {done: true}
iter.next() // {done: true}"Basic" use of generator functions is to simply yield values and create a sequence, sending values out of the generator function (through the iterable) at the rate the consumer desires.
– Domenic Denicola
function * bananas () {
while (1) {
yield "banana"
}
}
function take (n, iter) {
let result = []
while (result.length < n) {
result.push(iter.next().value)
}
return result
}
take(2, bananas())
// ["banana", "banana"]Generators also have an "advanced" mode, where you can send values into the generator function
– Domenic Denicola
function double (genFn) {
let iter = genFn()
let value = 0
let done = false
while (!done) {
const next = iter.next(value * 2)
done = next.done
value = next.value
}
return value
}
double(function * () {
const a = yield 1
const b = yield 2
return a + b
}) // 6
import { coroutine } from "bluebird"
let superSteve = coroutine(function * (x) {
const y = yield inc()
return x + y
})coroutine (spawn) is a function that
inverts the normal consumer-producer
model of the generator to create iterable sequences
import { coroutine } from "bluebird"
let superSteve = coroutine(function * (x) {
const y = yield inc()
return x + y
})
function steve (x) {
const y = inc()
return x + y
}
async function superSteve (x) {
const y = await inc()
return x + y
}
function steve (x) {
const y = inc()
return x + y
}
async function superSteve (x) {
const y = await inc()
return x + y
}
function steve (x) {
const y = inc()
return x + y
}
async function superSteve (x) {
const y = await inc()
return x + y
}
usable today with transpilers like babel (stage 1)
async function superSteve (x) {
const y = await inc()
return x + y
}
usable today with transpilers like babel (stage 1)
declaratively say that we are going to wait on inc
async function superSteve (x) {
const y = await inc()
return x + y
}
usable today with transpilers like babel (stage 1)
declaratively say that we are going to wait on inc
the generator stuff is an implementation detail
async function superSteve (x) {
const y = await inc()
return x + y
}
usable today with transpilers like babel (stage 1)
declaratively say that we are going to wait on inc
the generator stuff is an implementation detail
async function superSteve (x) {
const y = await inc()
return x + y
}
async steveception (x) {
const a = await superSteve(x)
const b = await superSteve(a)
const c = await superSteve(b)
return a + b + c
}
usable today with transpilers like babel (stage 1)
declaratively say that we are going to wait on inc
the generator stuff is an implementation detail
async function superSteve (x) {
const y = await inc()
return x + y
}
async steveception (x) {
try {
const a = await superSteve(x)
const b = await superSteve(a)
const c = await superSteve(b)
} catch (err) {
console.error(err)
let a = b = c = 1
} finally {
return a + b + c
}
}
usable today with transpilers like babel (stage 1)
declaratively say that we are going to wait on inc
the generator stuff is an implementation detail
async function superSteve (x) {
const y = await inc()
return x + y
}
function pat (x) {
return inc()
.then(y => x + y)
.catch(::console.error)
}
function cam (x, cb) {
inc((err, y) => {
cb(err, x + y)
})
}
async function superSteve (x) {
const y = await inc()
return x + y
}
function steve (x) {
const y = inc()
return x + y
}
– by –
@mrdougal
– by –
@cccc00 – James Hunter