53 karma · joined May 27, 2016
For a Linux user, you can already build such a system yourself quite trivially by getting an FTP account, mounting it locally with curlftpfs, and then using SVN or CVS on the mounted filesystem. From Windows or Mac, this FTP account could be accessed through built-in software.
So in that sense, design can and should be fluid. Where I work, designers often meet with customers (some external, some not) and continually get feedback, which the developers act on. IMO stopping design as soon as development starts increases the chance of having a poor design, forever.
Sometimes it's not known that a design has flaws until things start coming together during a project and some workflows become more prominent (and painful) than others.
Of course, I'd also want to work outside of the office, with my colleagues too. A change of environment every now and then can't hurt.
In this case, you don't have to be accurate, you're just trying to call someones bluff, in the small case they've actually done said thing (and in addition believe you can prove it AND that payment will silence them)
As others are saying, it's not really something that is standardised (or strictly necessary), which is why you don't see it much.
It allows you to change brightness, contrast (and volume, never tried it), from the taskbar.
It works for a Dell and iiyama monitor I own, but not my Agon one, so YMMV
Why promises? Before promises, js code often used an error first callback strategy to communicate when an asynchronous process has finished. It's important to write blocking code as little as possible, since your computer can and should spend time doing 'compute' stuff, whilst waiting for a resource, such as a network request or disk etc.. which can take an unbounded amount of time.
Back to how callbacks look: ``` function myExpensiveSuccessfulFn(cbFn) { setTimeout(() => { cbFn(null, 'success'); // pretend we did something useful }, 60 * 1000) // time waste for a minute }
function myExpensiveFailingFn(cbFn) { setTimeout(() => { cbFn('oh no'); // pretend we tried to do something useful }, 60 * 1000) // time waste for a minute }
function myCallback(err, data) { console.log(`err: ${err}`); console.log(`data: ${data}`); }
myExpensiveSuccessfulFn(myCallback); // after 1 minute: err: null, data: 'success'
myExpensiveFailingFn(myCallback); // after 1 minute: err: 'oh no', data: undefined ```
Awesome. We can wait for some result and be notified whenever it finishes. Have a play in your inspector as before. Immediately after calling our expensive functions, we can execute code straightaway (try logging anything immediately after calling an expensive function)
Now callbacks start to get unwieldy when those same callbacks also want to do things that require something else asynchronously. There are better examples online, but I'll write something with anonymous functions to give you an idea:
``` function addSomethingSoon(a, b, cbFn) { // in 5 seconds, return the sum of two numbers setTimeout(() => { cbFn(a + b)// no err first style in this example }, 5 * 1000); }
// now let's get the sum of four numbers:
addSomethingSoon(1, 2, (result1) => { addSomethingSoon(result1, 3, (result2) => { addSomethingSoon(result2, 4, (finalResult) => { console.log(`1+2+3+4=${finalResult}`); }); }); }); ```
Only 3 operations, and things are getting quite ugly. Contrived, but let's see how we can do better.
Enter the promise. A promise is a 'promise' of a future result. It's like if you went to a fast food restaurant, made an order and got a ticket in return. Once you are given a ticket, they'll call out your number and give you your food, since you are holding the ticket (the promise of food in the future).
Let's have a play:
``` function getFoodIn5(menuItem) { // don't worry about the syntax here. You'll likely not be creating promises with 'new' often. You'll likely get given them from a library, say a http call or similar. return new Promise((onComplete) => { setTimeout(() => { onComplete(`fresh ${menuItem}`); }, 5 * 1000) }); }
const promiseOfFood = getFoodIn5('burger'); console.log(promiseOfFood) // depends on your browser, nothing very useful, and definitely NOT our burger....
promiseOfFood.then((food) => { console.log(food); // fresh burger, yes, it tastes so good! }); ```
So we got our burger, pretty fast too. Unfortunately they just hired a few trainees:
``` function burntFoodIn5(menuItem) { // don't worry about the syntax here. You'll likely not be creating promises with 'new' often. You'll likely get given them from a library, say a http call or similar. return new Promise((onComplete, onError) => { setTimeout(() => { onError(`burnt ${menuItem}`); }, 5 * 1000) }); }
const promiseOfFood = burntFoodIn5('burger'); console.log(promiseOfFood);
promiseOfFood.then((food) => { console.log(food); // ... :( nothing }).catch((mistake) => { console.log(mistake) // burnt burger, you don't want to eat this. }); ```
that is promises in a nutshell. doesn't seem very useful now, but they are composable:
``` function add2(a, b) { // return a promise NOW, that will give us the sum of two numbers in 5 return new Promise((onComplete) => { setTimeout(() => { add2(a + b) }, 5 * 1000); }); }
add2(1, 2).then((result1) => { return add2(result1, 3); }).then((result2) => { return add2(result2, 4); }).then((finalResult) => { console.log(`1+2+3+4=${finalResult}`); }); ```
Now we don't have the masses of indentation of callback hell. Note that will take the same amount of time to run as the callback example. Promises don't make anything faster, they just help us to write synchronous looking code. The next step to bring us back to imperative looking code is async/await. But that's for another time.
Finally, the best way to learn is to do. Get a hold of VSCode, and get the Quokka extension. You can then `Ctrl+Shift+P` or `Cmd+Shift+P` and `Quokka: new javascript file`, and get a real time repl where you can mess around and log to your hearts content to get a feel of things.
You can think of a prototype as 'cloning' an object (but not quite), distinct from classes in OOP, which are typically created afresh, i.e. no entanglement occurs between instance 1 and 2 of the same class (unless of course explicitly specified in a constructor). If I have `var a = {one: 1, two: 2}`, I can use that as a 'live template' to stamp out other 'instances' that prototypically inherit from that ancestor. Any attribute lookups that are not specified directly on an object created with a prototype recursively look up the prototype ancestry chain until it is found. So if c -> b -> a (where a -> b means a prototypically inherits from b), looking up a property on c will try to look for the property on c first, failing that b, then a. If nothing is found, `undefined` is returned.
Let's open our inspector and have a play: ``` var a = {one: 1, two: 2}; var b = Object.create(a); // create b, based on prototype a var c = Object.create(b);
console.log(c.one) // 1, how, when this wasn't even defined! We looked up the p. chain until we found it
b.three = 3;
console.log(a.three) // undefined, a's only prototype is Object console.log(c.three) // 3, wow, c knew about something that happened to b! This is different from OOP. 'instances' share data defined at runtime.
```
If it could recover fast enough to play the right audio in time, then it would seem that bluetooth is already low latency enough to play in real time anyway? Or am I missing something.
Your explanations were surprisingly simple
the fix is to do away with @types and export types from the dependency itself so they are always in sync
as an aside I think Google home users leverage this to turn on their TV, which I think is pretty cool