I was given a Dualit Classic Newgen 4 slice toaster as a wedding gift.
It was without a doubt the WORST toaster I have ever used.
I've never been so annoyed by a product before. In fact, it annoyed me so much that I ended up returning it and replacing it with a cheap toaster that is 10% of the price and functions better.
I'll list the fatal flaws with it in descending order of importance:
1) Unlike basically every single other toaster on the market, it does not have a cage or other mechanism that closes on to the bread slices and keeps them an equal distance from the heating element. This results in at least one part of every single slice of bread getting burned to a crisp, and at least one part of every single slice not being toasted at all. After using this toaster for a week, I couldn't believe how any engineer at Dualit could release this. Do they even use their product? It is a catastrophic oversight.
2) The timer is an analogue mechanism, much like an egg timer. I found that there was an extremely thin margin in which the toast is toasted. Anything under that and it's not, anything over that and it's burned beyond recognition. I cannot even count the number of times the smoke alarm in my house went off because my toaster burned my bread to a crisp. Another catastrophic oversight.
3) Because the timer is analogue, when you turn it it makes a clicking noise as an egg timer does. This means it's very easy to mistake the toaster for being on, when in fact it's not. The number of times I went to make toast, only to realise a few minutes later that the toaster was unplugged for some reason and my bread was still bread is unreal. I'd then end up ruining my scrambled eggs by waiting another few mins for toast.
4) The toaster allows you to spin a dial to choose how many heating elements to use. This is a pain in the ass. It's so easy to forget about, until you go to pick up your toast and find out that only 1 and a half slices have been toasted of the 4 you put in there.
The sad thing is, the toaster looked awesome. We also have a Dualit kettle (which is great) and it matched. Unfortunately they prioritised aesthetics over function, and it shows. If you want a toaster that requires you to go through a checklist of switches to check before operating, then requires constant supervision to avoid burning your toast, and will still give you burnt sections of toast anyway despite all of that, I could not recommend a better candidate.
Are you perfectly rational and calm when trapped in a malfunctioning vehicle that could harm you on a whim? I feel it's unfair to judge this person sitting relaxed in front of a computer.
Doing multiple async tasks concurrently as opposed to in sequence. If you have never used this you have either worked on extremely simple systems or have been leaving a ton of perf gains on the table.
If each await was to a setTimeout call waiting 1000ms, awaiting all 3 would take approximately 3000ms.
If you await a Promise.all with an array of the promises, it will take approximately 1000ms.
In summary, using individual awaits runs them serially, while Promise.all runs them concurrently.
If you’re doing CPU bound work without workers, it doesn’t make much of a difference, but if you’re doing I/O bound tasks, like HTTP requests, then doing it in parallel will likely make a significant difference.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function test() {
const start = new Date;
const promises = Array(3).fill(null).map(() => delay(1000));
for (const p of promises) await p;
const end = new Date;
console.log("elapsed", end - start); // shows about 1010
}
test();
You're starting all three promises, then waiting for the first one to finish, then waiting for the next one, then waiting for the last one. But because they were all started at the same time, they'll be run in parallel.
Whereas if you started one promise, waited for it to finish, then started the next and so on, it would take the three seconds as they won't be run in parallel.
The code you've written can be seen as a "poor-man's" Promise.all, in the sense that it's doing roughly the same thing but less clearly. It also behaves slightly differently in terms of rejections: if the final promise in the Promise.all version rejects immediately, then the whole promise will fail immediately. However, in your version, if the final promise rejects, that rejection won't be evaluated by the await (and therefore thrown) until all the other tasks have completed.
For reasons of clarity and correctness, therefore, it's usually better to just use Promise.all rather than awaiting a list of already-started promises in sequence.
In order to use `Promise.all`, you'd still have to construct all the promises without awaiting them. That seems like the whole foot-gun and cognitive load right there.
But the early rejection is a concrete improvement over the "poor-man's" version. I'm sold.
So the timing of your for...of loop is that the first element probably takes about 1000ms to complete, and then the other two seem to happen instantly.
Promise.all is just an alternative to writing the for...of await loop:
await Promise.all(promises);
I guess it relies on you already being familiar with the Promise API, but I feel that Promise.all() has slightly less cognitive load to read and its intent is more immediately clear.
A strong case for preferring the Promise.all() is that Promise.allSettled(), Promise.any() and Promise.race() also exist for working with collections of promises, and unlike Promise.all(), they would not be so easily reproduced with a one liner for...of loop, so its not unreasonable to expect that JS developers should be aware of Promise.all(), meaning there is no reason for it not to be the preferred syntax for the reasons I stated above.
Ok, I'm a believer. I misled myself into thinking there was more going on with Promise.all than there really was. I'm mildly averse to allocating unnecessary arrays. But this is mostly superstition rather than measurable performance concern.
Promise.allSettled has a poor-mans implementation too. But the others really don't have such a thing.
My impression is that Promise.all() is kind of nice, but it's really not that big a deal or important. If it didn't exist, you could get the same happy-path code behavior without really even changing the size of the calling code.
But there's nothing wrong with it really. On balance, it seems slightly nicer than the poor-man's re-implementation. In the last 5 years, I might have been able to use it maybe twice.
I think you are confusing the speed at which the earth orbits the sun (~29.8km/s) with the speed at which an object needs to travel to maintain earth orbit (~7.8km/s).
Whoops, you are right. I think it's too late to edit my original post.
The point still stands, though, you have to get to nearly 8km/s otherwise you aren't in orbit and you fall back into the atmosphere.
You can't get to anywhere near that speed while still in the atmosphere - SR-71s only manage about 1km/s, and because kinetic energy is proportional to the square of the speed, at that point you are only 1/64th of the way there.
Umm isn't that the point of trying to reverse aging ..to look normally youthful not look so unusual that the look isn't youthful at all just unusual. Look at all the comments here that agree some saying the look is that of a vampire. Thats what the majority thinks and wishes for when it comes to reverse aging ..to be and look 20 again yet with all the wisdom and wealth gained over the years.
Just to keep the sarcasm going: Is there a scientific test that checks for "looking like a vampire"?. Cause he sure does to me, but I'm not a vampire-specialist, so what do I know...
This is beyond the Juicero level of startup nonsense.
Watching the video of Gerry Tan and the founder describing the design as “space warping” was tedious.
I'll list the fatal flaws with it in descending order of importance:
1) Unlike basically every single other toaster on the market, it does not have a cage or other mechanism that closes on to the bread slices and keeps them an equal distance from the heating element. This results in at least one part of every single slice of bread getting burned to a crisp, and at least one part of every single slice not being toasted at all. After using this toaster for a week, I couldn't believe how any engineer at Dualit could release this. Do they even use their product? It is a catastrophic oversight.
2) The timer is an analogue mechanism, much like an egg timer. I found that there was an extremely thin margin in which the toast is toasted. Anything under that and it's not, anything over that and it's burned beyond recognition. I cannot even count the number of times the smoke alarm in my house went off because my toaster burned my bread to a crisp. Another catastrophic oversight.
3) Because the timer is analogue, when you turn it it makes a clicking noise as an egg timer does. This means it's very easy to mistake the toaster for being on, when in fact it's not. The number of times I went to make toast, only to realise a few minutes later that the toaster was unplugged for some reason and my bread was still bread is unreal. I'd then end up ruining my scrambled eggs by waiting another few mins for toast.
4) The toaster allows you to spin a dial to choose how many heating elements to use. This is a pain in the ass. It's so easy to forget about, until you go to pick up your toast and find out that only 1 and a half slices have been toasted of the 4 you put in there.
The sad thing is, the toaster looked awesome. We also have a Dualit kettle (which is great) and it matched. Unfortunately they prioritised aesthetics over function, and it shows. If you want a toaster that requires you to go through a checklist of switches to check before operating, then requires constant supervision to avoid burning your toast, and will still give you burnt sections of toast anyway despite all of that, I could not recommend a better candidate.
reply