Ondřej Žára, @0ndras
Also known as The Callback Hell
getData(function(err, data) {
if (err) return displayError(err)
processData(data, function(err, result) {
if (err) return displayError(err)
displayData(result, function(err) {
if (err) return displayError(err)
})
})
})
Readable, but gets hairy when additional arguments are passed to individual callbacks
getData().then(
processData,
displayError
).then(
displayData,
displayError
).then(
null,
displayError
)
Readable, but needs the additional MAGIC
boilerplate that runs the generator and correctly links returned promises
let generator = function* () {
try {
let data = yield getData()
let result = yield processData(data)
yield displayData(result)
} catch (err) {
displayError(err)
}
}
MAGIC(generator)
The async
keyword defines an async function:
async function A() {}
let B = async function() {}
let obj = { async C() {} }
let D = async () => {}
The await
keyword can only be used inside of an async function:
async function A() {
let b = await B()
let c = await C(b)
return c
}
await
does nothingawait
interrupts the execution and waits for fulfillmentawait
throwsPromise-based code as readable as its synchronous counterpart
try {
let data = await getData()
let result = await processData(data)
return displayData(result)
} catch (err) {
displayError(err)
}
Parallel execution in JavaScript:
Passing data between Workers:
let sab = new SharedArrayBuffer(10) // bytes
worker.postMessage(sab)
let view = new Uint8Array(sab)
view[0] = 42 // will be eventually visible from the worker
SharedArrayBuffers
correspond to a memory that is truly shared across multiple workers (threads)view[0] = view[0] + 1 // Race Conditions 101
The Atomics
namespace holds functions that operate on SharedArrayBuffers
load() , store() | get/set values without instruction reordering |
add() , sub() , and() , or() , xor() | atomic arithmetics |
exchange(arr, index, value) | sets a new value, returns the old one |
exchangeCompare(arr, index, | sets a new value if the old one matches the expected one |
wait(arr, index, value, [timeout]) | blocks until a value is no longer present |
wake(arr, index, count) | wakes a given number of waiters |
JS objects can be iterated in multiple ways:
for (let p in obj) {}
Object.keys(obj)
Object.getOwnPropertyNames(obj)
All these variants iterate over property names (strings)
Object.values(obj)
Object.keys
)Object.entries(obj)
What are property descriptors?
let descriptor = {
enumerable: false,
get: Math.random
}
Object.defineProperty(myObj, "key", descriptor)
Object.defineProperties(myObj, {"key":descriptor})
Object.create(proto, {"key":descriptor})
Object.getOwnPropertyDescriptor(obj, "key")
Object.getOwnPropertyDescriptors(obj)
Object.defineProperties
Where are trailing commas already allowed (and ignored)?
[a, b, c, ]
{key: value, }
New in ES2017: argument lists
function x(a, b, c, )
x(a, b, c, )
When | Event |
November 2015 | First draft of the padStart/padEnd proposal |
March 2016 | left-pad incident |
June 2017 | padStart/padEnd accepted into the standard |
Method names are chosen to be independent on writing direction
"test".padStart(7, "!?") // "!?!test"
"test".padEnd(7) // "test "