Selfishly, I prefer when you cover intermediate/advanced/niche topics like these as there's already a deluge of beginner-level content. But I get that beginner content can draw more views which would yield a higher return on the effort you put it. I don't mind the occasional TypeScript video either. Honestly man, you do you. I find your videos to be a cut above the rest generally.
to answer your question YES demo-ing how to resolve some of the problems that you or people you know might have encountered is probably very helpful for a lot of us out there Keep it up !
Very nice video, but you have a race condition. Look at that code: let a = []; a[2] = "hello"; console.log(a.length); // === 3 Your overall mapPromises does not resolve when all promises resolve, it resolves when the last promise resolves (function next, line 20).
ooooh, that's a really good catch! I guess the simplest way to solve it is with `let completed = 0`, increment in the final `then`, and check that `completed === args.length`. Thanks!
Another quick fix could be to check for `Object.keys(results).length` instead of `results.length`. But the `let completed = 0` approach is probably is more readable.
this is a really cool concept! glad to have watched to the end because the whole time it seemed like there _must_ already bee some API for this, but yours is unique. It's pretty neat how you managed to do it so succinctly, too!
Your .then() is always run on an almost empty stack - this is part of the A+ spec and reflects the original semantics in E. The only thing there is a resolver, but the promise itself is unused, so it's not that different to explicitly using setImmediate afaict.
setTimeout is a drop-in replacement for setImmediate and has browser support. If not given a delay parameter it behaves as if passed a 0, so just like setImmediate. But in your case I think it would be fine dropping it altogether. I can't see the drawback of simply using `.then(next)`. They are not really bound to each other because your next function never returns anything.
It’s better to use finally than then in case catch throws, but in your case then will work. I think finally has better semantics for what you want to convey
9 місяців тому
TypeScript and JavaScript videos are awesome!! Please go ahead with both types!!
first of all YES! second, I have a comment on the implementation, there's a possibility (in the case that the concurrency limit is 3) that either one of or both of the 2 jobs before the last one finish after the last one does; in this case the returned results list will have their corresponding values in the results array as undefined, and also callback will be called more than one time. possible solutions I could think of: 1- do a filter operation on existence of values before checking for equality with the inputs array length; else if (results.filter(Boolean).length == inputs.length) 2- use a Map keys as the index of the result in the array and values as the result; verify using map.size rather than results.length; then when you finally resolve, you can map it into an array again
setImmediate unlike the name won’t run “as soon as possible” instead it will enqueue the task at the end of the current loop iteration. If you need something to execute in the same tick or “as soon as possible” use process.nextTick instead The naming is messed up IK but its just a little node gotcha
You're not implementing the concurrency flag like you said you would. It's acting more like a count of promises to start, and not an an amount of promises to schedule at a time... correct me if I understood incorrectly.
There is a huge bug in your code! The results are returned in the order they were resolved, NOT the order they appeared in the original args array. Make a function that has the functionality “given n, wait 10-n seconds then return n” and run it with an array 0 through 9 and a concurrency of 10. The numbers will be returned in reverse order.
You seem to be pretty good about making videos on interesting topics, TypeScript or not. So in my opinion just keep doing what you're doing, if you find something you think is worth making a video about, it probably is.
Both .catch(onRejected) [aka .then(undefined, onRejected)] and .finally(onFinally) [aka .then(onFinally, onFinally)] are simple aliases of .then(onFulfilled, onRejected). So with that in mind, your code would be better structured as .then(onFulfilled, onRejected).then(onFinally) rather than the current .then(onFulfilled).catch(onRejected).finally(onFinally). I would highly recommend reading the MDN docs on .then(), you should find them informative.
Selfishly, I prefer when you cover intermediate/advanced/niche topics like these as there's already a deluge of beginner-level content. But I get that beginner content can draw more views which would yield a higher return on the effort you put it. I don't mind the occasional TypeScript video either. Honestly man, you do you. I find your videos to be a cut above the rest generally.
to answer your question
YES
demo-ing how to resolve some of the problems that you or people you know might have encountered is probably very helpful for a lot of us out there
Keep it up !
Very nice video, but you have a race condition. Look at that code:
let a = [];
a[2] = "hello";
console.log(a.length); // === 3
Your overall mapPromises does not resolve when all promises resolve, it resolves when the last promise resolves (function next, line 20).
ooooh, that's a really good catch! I guess the simplest way to solve it is with `let completed = 0`, increment in the final `then`, and check that `completed === args.length`. Thanks!
Another quick fix could be to check for `Object.keys(results).length` instead of `results.length`. But the `let completed = 0` approach is probably is more readable.
yeah that works too. I don't love the extra unnecessary iteration of results, though.
this is a really cool concept! glad to have watched to the end because the whole time it seemed like there _must_ already bee some API for this, but yours is unique. It's pretty neat how you managed to do it so succinctly, too!
i agree
Your .then() is always run on an almost empty stack - this is part of the A+ spec and reflects the original semantics in E. The only thing there is a resolver, but the promise itself is unused, so it's not that different to explicitly using setImmediate afaict.
Awesome! Maybe you could start the video with a quick demonstration of how your end solution can be used/called, and then start building it
This is exactly what kind of videos i am looking for. Getting to know how we can use them properly
setTimeout is a drop-in replacement for setImmediate and has browser support. If not given a delay parameter it behaves as if passed a 0, so just like setImmediate.
But in your case I think it would be fine dropping it altogether. I can't see the drawback of simply using `.then(next)`. They are not really bound to each other because your next function never returns anything.
Awesome! Nice feature to work on; executed quickly and with clear explanations. Thanks a lot for this one (and yes, please, continue on this path).
It’s better to use finally than then in case catch throws, but in your case then will work. I think finally has better semantics for what you want to convey
TypeScript and JavaScript videos are awesome!! Please go ahead with both types!!
first of all YES!
second, I have a comment on the implementation, there's a possibility (in the case that the concurrency limit is 3) that either one of or both of the 2 jobs before the last one finish after the last one does; in this case the returned results list will have their corresponding values in the results array as undefined, and also callback will be called more than one time. possible solutions I could think of:
1- do a filter operation on existence of values before checking for equality with the inputs array length; else if (results.filter(Boolean).length == inputs.length)
2- use a Map keys as the index of the result in the array and values as the result; verify using map.size rather than results.length; then when you finally resolve, you can map it into an array again
Oh! I just watched your next video, your solution using the `settled` counter is much simpler. Thank you for that one
Absolutely more of this advanced stuff!
I actually loved it, I'd appreciate to see it again but typescript is also fun as well.
Yes, this was an awesome video! I'd love to see more of this.
Love your videos, there is always something to learn from you. Keep doing it
Would love to see more of this👍
Pretty nice.
Small comment. The function is not universal and difficult to describe types for it.
Here is the typed one:
type Task = () => Promise;
type TaskResult = T extends Task ? R : never;
const concurrentAllSettled =
(concurrency: number, ...tasks: T): Promise => new Promise((resolve) => {
const count = tasks.length;
const results = Array(count).fill(undefined) as { // PACKED_OBJECTS
[K in keyof T]: PromiseSettledResult
};
let current = 0;
let settled = 0;
const next = () => {
if (settled === count) { resolve(results); return ; }
const index = current++;
const task = tasks[index];
task()
.then(
(value) => { results[index] = { status: "fulfilled", value }; },
(reason) => { results[index] = { status: "rejected", reason }; },
).then(
() => { settled += 1; next(); },
);
};
while (concurrency-- > 0) next();
});
Use of setImmediate was beautiful. Introduced me it so thanks
love any kind of videos that you make.
Nice job dude 🎉
setImmediate unlike the name won’t run “as soon as possible” instead it will enqueue the task at the end of the current loop iteration.
If you need something to execute in the same tick or “as soon as possible” use process.nextTick instead
The naming is messed up IK but its just a little node gotcha
You're not implementing the concurrency flag like you said you would. It's acting more like a count of promises to start, and not an an amount of promises to schedule at a time... correct me if I understood incorrectly.
I`m really curious about that call stack situation. How is that even a thing? Actually have no clue how call-stack(s?) works
Cool video! Thanks!
Just out of curiosity: I solved this same problem during a coding interview at Uber, in 2021.
that's funny; I interviewed at Uber last year and got the same problem during my interview but it was using callbacks instead of promises
As long as it's intermediate or advanced level... I like a nice mixture of TypeScript and JavaScript.
Love both kinds of videos
this kind of video is really cool
Both types of videos are good. Mix it up!
What font is that I love it?
atm i'm doing only django/oscar work, man i miss js. to answer your question: yes, more please!
There is a huge bug in your code!
The results are returned in the order they were resolved, NOT the order they appeared in the original args array. Make a function that has the functionality “given n, wait 10-n seconds then return n” and run it with an array 0 through 9 and a concurrency of 10. The numbers will be returned in reverse order.
Won't wrapping the contents of the mapPromises function in a promise do the same as using this new, experimental feature? Or am i missing something?
You seem to be pretty good about making videos on interesting topics, TypeScript or not. So in my opinion just keep doing what you're doing, if you find something you think is worth making a video about, it probably is.
what font are you using in the IDE?
I'm in for both kinds of videos, or different ones too :)
Hi andrew love your videos ! Btw can you make a video about map in javascript such when we should use it instead of plain object. Ty ❤
does the index start at 1 since cursor is incremented?
what’s that font??
Can generators be used here?
what about both Andrew 😄
P-map for node20 ;)
what is the name of your font?
monolisa :)
you look like the guy from Planetscale teaching database so much, it's confusing
it also doesn't help that they both have square glasses 😂
Both .catch(onRejected) [aka .then(undefined, onRejected)] and .finally(onFinally) [aka .then(onFinally, onFinally)] are simple aliases of .then(onFulfilled, onRejected).
So with that in mind, your code would be better structured as .then(onFulfilled, onRejected).then(onFinally) rather than the current .then(onFulfilled).catch(onRejected).finally(onFinally).
I would highly recommend reading the MDN docs on .then(), you should find them informative.