forEach is BAD! for Async Await Code | Advanced Async/Await Javascript Tutorial

  Рет қаралды 72,007

Dave Gray

Dave Gray

Күн бұрын

Пікірлер: 248
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
forEach is not the right choice for Async / Await code. In this tutorial, you will learn about 4 alternatives to forEach that will work when you are writing async code. If you are just starting out with Javascript, I suggest my full 8 hour Javascript tutorial here: kzbin.info/www/bejne/e5eknWyYrN-JkM0
@ocoolsanni2803
@ocoolsanni2803 2 жыл бұрын
Thanks for the tutorial and the info I've been looking for... I've got a question since I'm more interested in the reduce function and I'd love to try it out. How would you slower it when web scraping?? Would you use the timeout function since JavaScript doesn't have a sleep function??
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@ocoolsanni2803 I'm not sure how this applies to web scraping. You can use an interval in JS to time the requests if needed.
@ocoolsanni2803
@ocoolsanni2803 2 жыл бұрын
@@DaveGrayTeachesCode Thanks for the quick responce and guidence, in an api i'm working on. Looking foward to a scrapping tutorial from you
@Gameplayer55055
@Gameplayer55055 2 жыл бұрын
replacing foreach with for helped dramatically, now my entries don't hang page for 4 seconds
@hasithadhananjaya2806
@hasithadhananjaya2806 2 жыл бұрын
dear sir, I'm begginer for JS, what is the frame work I should learn first NODE or REACT or else. Please!.
@Bayo106
@Bayo106 3 жыл бұрын
as soon as I saw this title I had an epiphany and watching it helped me solve something at work. thank you so much
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
That's great to hear! 💯
@cedigasser
@cedigasser 2 жыл бұрын
Actualy, await Promise.all() returns an array in which the results are in the same order as the promises they're from. This is usefull if you don't need to wait after each promise but still need them in sequence.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Agreed as discussed in a few of the other comments. 💯
@absbica31
@absbica31 2 жыл бұрын
@@DaveGrayTeachesCode does this mean line 25 at the end?
@Cerbeh
@Cerbeh 3 жыл бұрын
Really cool seeing the reduce example. I recently used it myself to serialise a bulk file upload due to size limits on our API. Had never seen it before and now here you are making a video explaining it too!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
And you just described a great use case! Nice! 💯🚀
@maestrocode9164
@maestrocode9164 2 жыл бұрын
Would a for-of loop do the same? I fail to see the difference
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@maestrocode9164 if you watch the video you will see the for of loop demonstrated as well.
@glennadams8833
@glennadams8833 3 жыл бұрын
I've struggled to get serialized data from multiple async function calls and this clears up a lot. Aside from when not to use a forEach method, the gem in your lesson is going deeper into async/await and map/reduce methods. Cool!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Glad it helped Glenn 💯
@NguyenNguyen-ek4zq
@NguyenNguyen-ek4zq 2 жыл бұрын
I enjoy watching the reduce alternative. However, what made me unrest there is the callback of reduce without a return statement. Turns out that with async await and without an explicit return statement, you actually implicitly return a promise resolve undefined. That could have been explained in the video. Anw, thanks for a great video.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good note! 💯
@benarcher372
@benarcher372 3 жыл бұрын
"To get the job done". Most of the time that's all that matters. Thank you Dave for all your great JavaScript tutorials.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
You're welcome 🙏💯
@takahiro0127
@takahiro0127 2 жыл бұрын
I falled into this pit once. It took me days to find out the reasons and fix with the for ... of approach. At that time not many articles I could find on this topic. Thanks for making this video. This really do help.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you for the kind words, Chris 🙏 You're welcome! 💯
@lalitpatil7972
@lalitpatil7972 2 жыл бұрын
2 days before I was struggling with this forEach with async issue and today I saw your video. Saved my day. Thank you.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad it helped! 💯
@pellax
@pellax 2 жыл бұрын
Trying to improve my Javascript, great video, subscribed
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you! 💯
@dweblinveltz5035
@dweblinveltz5035 2 жыл бұрын
I love the reduce method. So many different applications for it; having said that, I really hope not to see this usage out in the wild. The first three variations were clearer, easier to read, and more effective. One thing I really don't like is the "magic" that seems to be occurring. When I first glance at it, my first question is, "Why isn't the callback returning something?" I can imagine every new dev being thrown off by how that works.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Great comment, Dweblin! 💯
@quinndirks5653
@quinndirks5653 2 жыл бұрын
Took me a good 5 minutes to figure it out, lol. I can definitely see how it would take a newbie much longer. It should be called "previousPromise" instead of "accumulator"... once you figure out the reason that is, then you must understand it. "async" functions return promises, even if the async function body returns undefined, either explicitiy or implicity, it will implicitly return a promise, but it will resolve to undefined, or whatever the value was that was returned by the async function body. So, in the context of the reduce method example, that means the accumulator, or "previousPromise", is always a promise that resolves to undefined, since, one, the callback was "async", meaning it returns a promise, and two, the callback did not return a value, meaning the promise will resolve to undefined. And, although the iterations are executed instantly for every id within the reduce method, which could result in asynchronous out-of-order execution when the "getPost" promises resolve at different times, it doesn't since the return value of each iteration is passed into the next iteration, and that return value (which is a promise) is awaited in the next iteration, which effectively lines the calls up and makes them wait for the previous iteration to complete before executing the next iteration. Gah, what a headache to understand. I much prefer the await promise.all solution.
@RD-jr8nv
@RD-jr8nv Жыл бұрын
Reduce is so versatile, can do a million things with it. This was really neat
@DebdutBiswasOnline
@DebdutBiswasOnline 2 жыл бұрын
Awesome, learned a lot. I was facing exactly a same problem to asynchronously send multiple separate emails by iterating an array fetched as database result.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad I could help! 💯
@caffeinated-pixels
@caffeinated-pixels 3 жыл бұрын
Good stuff Dave. It's interesting that when you learn functional programming in JS, you are constantly told that using for loops is bad because it's imperative, but I guess that's not always the case! Anyway, that reduce method is cool.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Right on 💯
@AntonioSantos-ve6zv
@AntonioSantos-ve6zv 2 жыл бұрын
Kind of advanced for me at this point, but it's put so clearly I've learned a lot. Thanks!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome, Antonio! 💯
@yadusolparterre
@yadusolparterre 2 жыл бұрын
12:19 You could have refactored your code in a cleaner way: const posts = Promise.all(ids.map(getPost)) No need for an async function if you are not going to await anything
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Agreed, but also noting for others reading this that await is needed before the Promise.all. Always improving - while the overall point of this video is solid, the Promise.all part is the area I would refactor. I'd still like to make a separate Promise.all video.
@irobot8297
@irobot8297 Жыл бұрын
dude you seem junior, go back to mdn
@kumar-jatin-2000
@kumar-jatin-2000 Жыл бұрын
Thanks Dave. I learned this lesson the hard way. I was using venom-bot and xlsx to automate sending a bunch of whatsapp messages to someone. I tried using forEach and async. That didn't end well lol.
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Glad this helped!
@urssaf343
@urssaf343 2 жыл бұрын
Let's not forget "for await... of" loops and "generators" solution.
@timderks5960
@timderks5960 2 жыл бұрын
Great video. In the beginning I was very adamant that forEach was a great choice given your examples, since it runs the promises concurrently. I must admit, your other approaches do a better job of making it actually clear that things are running either in serial or concurrently, and clarity is everything in code. I did kinda miss an example of how to use a concurrent method with a simple sort to get the same result as a serial process, only much, much faster. I understand that wasn't quite the scope of the video, but somebody who's just getting into this kind of stuff may now be convinced that serial HTTP requests is the only way to get serial data.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thanks, Tim! Yes, the focus here was keeping the request / response in the order expected and how forEach can provide surprising results. If you want to share a Github gist link with a concurrent method that is sorted, that would be a welcome addition!
@focusiam2027
@focusiam2027 Жыл бұрын
Road to 500k, congrats for the 100k🎉🎉🎉🎉
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Thank you!! 🚀
@rajapboyev3928
@rajapboyev3928 2 жыл бұрын
Big thanks to Dave Gray, very good explanation😃
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're very welcome! 🙏
@samirsamir7779
@samirsamir7779 3 жыл бұрын
Thank you Dave for this super great dev. Channel as Well as your Teaching way .
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
You're welcome, Samir! 💯
@cas818028
@cas818028 2 жыл бұрын
Devs care about other devs and their mental health. Please don’t ever use reduce this way. Thank you
@torinzhou2626
@torinzhou2626 2 жыл бұрын
That’s amazing Dave! You’ve made it crystal clear! Thanks for you efforts!👏👏👏👏
@torinzhou2626
@torinzhou2626 2 жыл бұрын
And I’m heading to your pure function video😀Have a strong feeling I would regret if I miss that one.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@brightmatter
@brightmatter 2 жыл бұрын
Concurrent also has a bigger issue. If you attempt to do too many concurrent operations at once you can begin quasi-blocking other operations because you are clogging the thread with to many requests for work at once. The way to handle this is designing a limited concurrent operation stack/queue. I've made them in the past, but I used callbacks, timers, and recursion. Modern implementations would likely use promises, and I'd love to see how that is done.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
In this video, I demonstrate several alternatives that do indeed work by awaiting promises to fulfill. 💯
@kevinbatdorf
@kevinbatdorf 2 жыл бұрын
forEach should always be used when you can (and have side effects). It’s a declarative approach that abstracts the implementation (and optimizations) to the browser.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Yes, forEach creates side effects. I prefer map, filter and other approaches when possible due to this. The video does not say you shouldn't use forEach. It does say it doesn't work the way many expect it to when they combine it with async requests.. and it provides a few alternatives to that approach.
@kevinbatdorf
@kevinbatdorf 2 жыл бұрын
@@DaveGrayTeachesCode At the beginning you heavily imply it shouldn't ever be used. But it should actually be preferred in all cases where you would otherwise use a for loop and have side effects, except the case you demonstrated (async/await). The declarative approach lets the browser optimize the implementation.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@kevinbatdorf the title of the video speaks only to async/await. If it seems I imply forEach should never be used for other uses, it was not intended.
@BrianVanderbusch
@BrianVanderbusch 2 жыл бұрын
@@DaveGrayTeachesCode just look at the poster frame for this vid... It really strongly implies "don't use for each".
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@BrianVanderbusch agreed. It's an attention getter and has generated a few unintended flames.
@shrooobdude
@shrooobdude 2 жыл бұрын
I'm a bit late to this video, but Promise.all does retain the order. Think of it as passing an array of promises, when each promise resolves they are transformed into their resolved value, but their position in the array does not change. So while they resolve at different times, the order is retained. I hope this makes sense :)
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
It does make sense. I don't think I said Promise.all wouldn't work? It's been months so I would have to watch it myself 😃
@shrooobdude
@shrooobdude 2 жыл бұрын
@@DaveGrayTeachesCode oh no you never said Promise.all wouldn't work - just that the order may not be retained 😁
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@shrooobdude ah I see! I'd like to make a separate Promise.all video as well.
@johnmcaulay4348
@johnmcaulay4348 2 жыл бұрын
Learnt this one the hard way the other day, should have been paying more attention to your videos!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
This one is catches many by surprise. 💯
@TarekFaham
@TarekFaham 2 жыл бұрын
I needed this in a project coming up soon. Thanks a lot for your help.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad I could help!
@janjankowski8701
@janjankowski8701 2 жыл бұрын
A small addition to the last serialized example: const getPostsSerialized = async (ids) => { const result = await ids.reduce(async (acc, id) => { const prev = await acc; const post = await getPost(id); console.log(`post id - ${id}:`, post); return [...prev, post]; }, Promise.resolve([])); console.log("result:", result); } Allows you to receive an array of all returns by the end like promise.All()
@john_paul_r
@john_paul_r 2 жыл бұрын
Worth noting that Promise.all will maintain the order that you pass the promises to it. The promises can complete in any order, but the returned results will always match the order of the passed array of promises.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Agreed, and noted in some other comment discussions, too. The array holds the order. Thanks! 🙏💯
@mohamedamineboukraia5528
@mohamedamineboukraia5528 2 жыл бұрын
What a great tutorial Dave!!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you, Mohamed!
@alexanderkomanov4151
@alexanderkomanov4151 2 жыл бұрын
I really happy that I found your channel. Your manner of explanation is the one of the best I saw. Thanks a lot for the content! Describe and big like from my side!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@gradar7891
@gradar7891 2 жыл бұрын
Most informative tutorial I’ve ever encountered for recent years 😄
@subhajitpanja1353
@subhajitpanja1353 2 жыл бұрын
Sir, you are the best JS teacher to me. Thank you for your efforts in making these videos. When I watch your video concept of that tropic getting clear. I have already requested you to make a video on React testing. That subject I want to learn from you.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you for the kind words and again for the request! 🙏
@cleancode2123
@cleancode2123 3 жыл бұрын
Nice one learned a lot !.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Glad to hear that! 💯
@0xAndy
@0xAndy 2 жыл бұрын
Thank you so much. I'm a new subscriber and really enjoy the channel so far.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Welcome aboard! 🚀🚀
@jollybeancomedy
@jollybeancomedy 2 жыл бұрын
Thank you for the video! The forEach not executing in order thing once got me into trouble, hope I had noticed it earlier.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@manujohn5346
@manujohn5346 2 жыл бұрын
Wow...very helpful. Wish I had seen this few months back. Would have saved me a ton of time😅
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad I could help! 🙏
@basilistigris640
@basilistigris640 3 жыл бұрын
one more masterpiece Javascript video lesson, very professional and perfectly explained lessons in javascript, very orginized channel, i learned a lot, thank you Dave Gray!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Thank you for the kind words, Basilis! 🙏
@zoaybk
@zoaybk 2 жыл бұрын
map approach was the best one I think, great video thanks
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@hv7460
@hv7460 2 жыл бұрын
Thanks a lot....I was yesterday calling Restendpoint1 inside foreach and Restendpoint2 outside foreach.... and the requirement was that Restendpoint1 should be called before Restendpoint2 ...but could not figure out this weird thing about foreach.... Thanks for sharing this...
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome!
@dindoleonard
@dindoleonard 2 жыл бұрын
So glad i stumbled into this gold mine of a video
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you, Leonardo! 💯
@navazsharif6783
@navazsharif6783 2 жыл бұрын
Just came here after watching James Q Quick video that you are talking about at 11:00
@tomascarignano5002
@tomascarignano5002 2 жыл бұрын
This is amazing! Thank you for the great explanation
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're very welcome! 💯
@arminmatthes
@arminmatthes 2 жыл бұрын
What I don't like about the reduce example is that you can't really return the resulting values as an array because you've put the promise into the accumulator... You don't always just want to log the result in the callback. You could pass in an object {lastPromise: null, result: []} and then adapt your code accordingly - if lastPromise is null, just dispatch the first Promise, then skip ahead to the next call. After awaiting the promise, push the result onto acc.result. Voila - you can have the cake and eat it, too. I just made this up without actually testing it, but it should work.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good note, Armin! 💯
@arshiagholami7611
@arshiagholami7611 3 жыл бұрын
I really liked the idea of using reduce here, never seen something like this. thanks for the great vid
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
It is an interesting use. Thanks for the comment! 💯
@TheDaviddoodles
@TheDaviddoodles 2 жыл бұрын
Hey Dave would you do some videos about Svelte I really love the way explain things
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you for the request! It may be awhile, but I'd like to do something with Svelte, too!
@kevinbatdorf
@kevinbatdorf 2 жыл бұрын
Never leave side effects in your reduce function. It should be a pure function that returns the accumulator. That console.log should be removed if anyone is using code from this video.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Yes, I do hope everyone understands to not leave console.log in any released code as you might see in a tutorial. You've got a long day ahead if you leave this note on any video using a console.log. Have a good day, Kevin!
@kevinbatdorf
@kevinbatdorf 2 жыл бұрын
@@DaveGrayTeachesCode That's fair. I felt the tutorial was well made otherwise so I wanted to point out a couple things that might affect new coders. Wasn't a dig on you personally.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@kevinbatdorf all good my friend. I didn't think it was, but I agree console.log should be removed from any examples used from a tutorial.
@laurentgauthier8742
@laurentgauthier8742 2 жыл бұрын
Super interesting! Thank you so much!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@nemanjasavic9859
@nemanjasavic9859 28 күн бұрын
Ooooooooo my god... I lost 2-3 hours because of this... I am lucky, you saved my ass.. A was using foreach.. Thank you so much
@vitason100
@vitason100 2 жыл бұрын
Hi Dave, Thank for this tutorial !!! Can you explain how we can handle error in this way, thank you.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Try / catch blocks are good for handling errors 💯
@luisaugsburger
@luisaugsburger 3 жыл бұрын
Thanks dude! nice explanation!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Glad you liked it! 🚀
@SkyrimBeast
@SkyrimBeast 2 жыл бұрын
Another great video Dave, many thanks. How could we go about fetching data from 2 API endpoints where the second API call depends on JSON data from the first API endpoint? Maybe this could be a future tutorial if you're so inclined.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good question and request! This requires waiting for one response before moving on to the next. I would use async / await and confirm success before moving to the next. In React, we use different states like isLoading, isSuccess, and isError to trigger different page renders.
@oksanakobyliatska6822
@oksanakobyliatska6822 2 жыл бұрын
Thanks a lot, that was very helpful!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad to hear that!
@PauloSantosk
@PauloSantosk 2 жыл бұрын
forEach respected the await instrucion, but It was executed recursively in a more performatic way. If you need order, sort the results.
@fParad0x_
@fParad0x_ 2 жыл бұрын
Do you have any info on how that works? I didn't know that forEach was executed in a different, special way.
@PauloSantosk
@PauloSantosk 2 жыл бұрын
​@@fParad0x_ it is part of the functional way of solve problems. It is executed utilizing recursion instead of a imperative instruction like the tradicional "for", for example. If you are executing asynchronous calls over a recursion loop, you cant wait the outcome in a ordered way and, "await" will not help too, because each call is in a diferent bubble of the stack and "await" will only wait in the same "bubble". But, you should use forEach every possible time, this video is misliding the importance of a functional way of solving the problems.
@BrianVanderbusch
@BrianVanderbusch 2 жыл бұрын
Exactly. "It doesn't return them in order" means it returned them in the order they resolved, and that's what asynchronous is really about.
@fParad0x_
@fParad0x_ 2 жыл бұрын
@@PauloSantosk Thanks for the explanation! Didn't know that.
@n1xx1
@n1xx1 2 жыл бұрын
This is straight up wrong information. forEach is iterative and not recursive, as you expect for something called "for each", however it's a synchronous function, it doesn't handle anything asynchronous inside. If the function you pass to forEach returns a Promise (that is what a async function is), it doesn't wait for it. It's not about being performant or faster, it just isn't what it's meant to do. Also it's not about sorting the result. If you do something like: const data = []; ids.forEach(async (id) => { const res = await getPost(id); data.push(res); }); console.log(data); Most probably data will be empty, because you didn't wait for any of the Promises to resolve. You probably want to go either the "reduce" or the "Promise.all with map" way, or just use a standard for loop. I would also like to point out that a for-of loop with awaits inside will execute the functions sequentially, waiting for the previous one to complete before starting the next one, while a const data = await Promise.all(ids.map(id => getPost(id)); Will execute them all at the same time, and return when all are completed. So they are not alternatives to each other, really.
@repenning1
@repenning1 Жыл бұрын
not sure why you would advocate using reduce over for_of. The main point of reduce is to bubble some computation such as a number accumulator not to just to chain promises. Of course you can serialize this kind of operation using reduce but this is unnecessarily complex because you are not reducing return values from async function but only promises. Makes more sense to let the for_of do this.
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
It's been awhile but I don't think I did advocate for anything over for_of. I think I showed several examples to use instead of for_each. I don't think I declared one example was above the others.
@rike7777
@rike7777 3 жыл бұрын
Very enlightening lesson. I really liked to see the difference between the serialized and the concurrent versions, as well as the use of reduce to solve the problem, although it is difficult to grasp at first. By the way, I also liked you VS Code Theme, which is easy on the eyes. Can you please tell me what it is? Thank you!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Glad you found it helpful. And yes, I just switched to this theme and really like it. It's the Github Theme. Several dark modes to choose from.
@LordValtrius
@LordValtrius 2 жыл бұрын
There's an issue with your reduce method. `await acc` isn't doing anything because you're not returning the promise. It's getting resolved instantly and moving onto the `getPost` which it is awaiting. Additionally you shouldn't use await within a loop (I never use it outside of a loop) because you have to wait for it to finish before moving onto the next iteration. Use `then` instead (which gets returned, obviously) so each request is "concurrent" but resolves in order. Also James Q Quick's code will also resolve in the correct order everytime as Promise.all returns an array of responses in the order the promises were passed in and would also be concurrent. Im replying on my phone but if you want an example of the reduce-then method just give me a shout.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Wow, I appreciate the time it took you to give such a detailed response. Thanks! Good discussion items even if we do not agree on all 😀 If this video wasn't about receiving a serialized response, I'd agree that 'await acc' isn't doing much in the reduce solution... but it very much is. If you remove it, your response results will not be in order (serialized). Maybe I should have said what my comment in the code says which is "waits for the previous item to complete" instead of saying it resolved.. but the concept is clear. I'd like to see some references on not using await in preference of .then() in a loop. I believe await is legitimate when used appropriately. I do agree on the Promise.all as I have discussed with others in these comments, too. My example does work as shown for Promise.all. However, I said it may not provide serialized results, but it indeed consistently does.
@LordValtrius
@LordValtrius 2 жыл бұрын
@@DaveGrayTeachesCode Hi. I wasn't sure if you would see my comment, never mind reply to it so thanks for that. You're right in that `await acc` is necessary for the loop to wait for the previous iteration. I didn't realise a promise is always returned from an async function even when not explicitly returned, did I mention I don't use async/await 🤣 I still don't think the waterfall approach is best for ajax requests. Here's my concurrent solution that acts on the data in a serialised way, reduce-ing the overall time taken. It's the best of both worlds from James Q Quick and your serialised approach since it can run on the data available while it waits for the next ajax req to finish. codesandbox.io/s/elegant-wiles-tvnqk6?file=/src/index.js
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@LordValtrius I appreciate the reply - and great share! Thank you! 💯🚀
@코린이31세
@코린이31세 3 жыл бұрын
Amazing lecture!!!! Thank you sir 👍👍
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
You're welcome!
@polinafeterman5057
@polinafeterman5057 2 жыл бұрын
Thank you for this explanation. Very clear and useful! Could you please tell me what is this extension that you called Dev Tools For Chrome? I can't find it in VS Code... Thank you!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
It is built into Chrome already. No extension needed. Right click your web page and choose "Inspect" from the menu to open dev tools. Or press Ctrl+Shift+I to open.
@jiweihe3413
@jiweihe3413 2 жыл бұрын
Thanks for the interesting video! I just have a naïve question. 3:10 I thought hoisting does not work for arrow functions, but it works for the useforEach() arrow function. Just curious why.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
That's a great question! I must have the initApp function defined before the event listener that calls it, but because I'm calling initApp with an event listener, it allows me to define everything else below. If I just called initApp() without the listener, this would not work. The DOMContentLoaded event has to fire before initApp is called. A similar explanation on StackOverflow: stackoverflow.com/questions/72235699/how-does-function-within-addeventlistener-gets-hoisted
@jiweihe3413
@jiweihe3413 2 жыл бұрын
@@DaveGrayTeachesCode I see. That makes sense! Thank you so much!
@saitejagatadi9711
@saitejagatadi9711 2 жыл бұрын
13:13 Dave, The mobile mode was on in browser. Not sure it was intentional 😄
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I usually have mobile mode on when I open Chrome Devtools.
@TheRishikesh99
@TheRishikesh99 2 жыл бұрын
the async foreach is weird because i would not expecting ordering in code that runs ASYNChronously. If you want ordering, you need to maintain it either with promise.all and map. Foreach is nice to have when you want async side-effects
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Agreed 💯 There is an example of using Promise.all in this video along with a few other possibilities.
@ericapinheiro9891
@ericapinheiro9891 2 жыл бұрын
Amazing reducing js!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you, Erica! 💯
@CesarScur
@CesarScur 2 жыл бұрын
The "problem" is not with the foreach concept. It is with the closure implementation of this foreach. Foreach is not evil.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Never said it was. This video is for those who try to use forEach when they want a serialized response.
@arminmatthes
@arminmatthes 2 жыл бұрын
I agree that it's important to know this beforehand, but it behaves exactly the way I'd think it should behave. To say that this should never be used in modern JavaScript is a bit dramatic. I use it all the time and I know what to expect. Oftentimes I don't need the data to be fetched in correct order. Besides, I think the bigger problem is that it can be hard to actually wait for all promises to resolve using forEach.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I think this video has been misunderstood a little based on the thumbnail without some seeing it specifically addresses async / await code and serialized results. There is nothing wrong with using forEach, but many expect different results when combining forEach with async/await. This video provides those looking for a solution with alternatives that give the functionality they expected to get when using forEach.
@decay6591
@decay6591 2 жыл бұрын
fixed redux thunk bug. appreciate. got sub
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad I could help!
@wojciechjarosz420
@wojciechjarosz420 10 ай бұрын
...and how to return fetched and resolved data from reduce function in this case?
@melpacheco9288
@melpacheco9288 Жыл бұрын
Masterful!
@randomnobody660
@randomnobody660 2 жыл бұрын
I'm not sure I see the issue? For each element in the array you asynchronously did some stuff to it (in this case called some api then logged the result), so of course each operation doesn't, and imo shouldn't, wait for the previous one to finish no? In fact why are we awaiting each fetch in the for loop anyways? I don't even understand what's in the video's opinion the better alternative; imo it would be more counter intuitive and less useful if you couldn't do async operations with foreach loops. Is the point just that foreach is a special case of map? I mean sure, but they express different intent (to the programmer/reader), which imo is important. Most branching statements are just conditional gotos with maybe some stack pushing and poping, yet people still somewhat pick and choose for this reason. I think it's quite expressive that you use reduce if you want each item to depend on the last, map if each item is independent, and foreach if the prior is true but you also don't care about return values. I'm sure there are legitimate gripes with foreach, but I didn't personally find this particular one convincing. Also also, if you really want it to "return" something you could always assign the promise somewhere then await outside no?
@randomnobody660
@randomnobody660 2 жыл бұрын
ok, so those are all talked about in the video as alternatives but again, what's the advantage of switching? Still not sure I understand.
@randomnobody660
@randomnobody660 2 жыл бұрын
plz no delete again...but foreach can also return like so: ``` const getPost = async id => (await fetch(funnyURL+ id)).json(); // i suspect the url is why youtube keeps deleting this const getPostsForEach = async ids => { let ret = []; ids.forEach((id, i) => ret[i] = getPost(id).then(console.log)); await Promise.all(ret); console.log('i\'m waiting fine?'); } ``` Also, like another gent mentioned, no need to async if you aren't awaiting. Also also, no need to await right before a return. In the case of getPost, the caller is going to get a promise if the caller doesn't await, or the promise if it does, whether you add that 2nd await or not.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thanks for all the input. Yes, all alternatives listed. Far too often I see beginners use forEach while awaiting promises and expect to get the results back in the order of the requests. The video points out that is not going to happen. For serialized results, the alternatives I've provided - and others have added in the comments - are better choices. The thumbnail for the video has brought out some stronger opinions, and at the same time garnered a few more views.
@krishanlanka7659
@krishanlanka7659 2 жыл бұрын
hi, can you correct my php if statement pls
@thecutedreamkostasp.4449
@thecutedreamkostasp.4449 2 жыл бұрын
Thx God there are better programmers than me. They make me bettter. I appreciate this sir.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I'd suggest avoiding thoughts about who is better or not. I always say keep striving for progress. A little bit every day is the goal. 💯
@MichaelMcGreal
@MichaelMcGreal Жыл бұрын
Nice use of reduce!
@luiizmorales316
@luiizmorales316 2 жыл бұрын
thanks bro... good video 👍🏽
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome!
@aman7555
@aman7555 3 жыл бұрын
Awesome 👌
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
🙏 Thank you!
@MaksymMinenko
@MaksymMinenko 2 жыл бұрын
12:40 The white screen of death. 😀
@DM-pg4iv
@DM-pg4iv 2 жыл бұрын
This is pretty cool. So is forEach just nlt a good idea ib general? Let's just say a regular func that you want to go through data. Is for of better?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Nothing wrong with using forEach for many needs, but if you desire a serialized response to requests, it is not the one to choose.
@sheelaveldurai2900
@sheelaveldurai2900 Жыл бұрын
how to break/exit the reduce loop and return the last value?
@TarekFaham
@TarekFaham 2 жыл бұрын
Do have tutorials about design patters in JavaScript? I'm looking for one to learn how to avoid using if then else statement using polymorphism. Can you help with this please?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I do not at this time, but it is a good idea! Thanks for your request!
@designcoded7585
@designcoded7585 3 жыл бұрын
most of the frameworks and peoples are using .map() only both for iteration like for loop os even for returing from the helper function , so far map is the popular way , so there no suprise , but for just practising we can use forEach() its nice
@Shubhaw
@Shubhaw 3 жыл бұрын
This is the exact same problem I faced last week in my office. Thanks for the solution. Although I would like to know why "await" doesn't work inside the forEach method body. Any links where I can read it in more depth?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
You're welcome. Yes, go down to the 2nd blue block on this page where it says "Note: forEach expects a synchronous function." developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
@Shubhaw
@Shubhaw 3 жыл бұрын
@@DaveGrayTeachesCode Thanks again! :)
@tyler8995
@tyler8995 Жыл бұрын
What's the extension that gives that line between your opening and closing braces?
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Here you go: kzbin.infoMDaxWffMjrQ
@tyler8995
@tyler8995 Жыл бұрын
@@DaveGrayTeachesCode thank you!
@djkos7
@djkos7 2 жыл бұрын
Dave, seriously, you need to get known what is async callback, why sync iterator does not care about it, how promises will be resolved in the callback Q, and for sure regarding functions context, and closures. From other side, forEach was made with only 1 aim - apply callback function in sync way for each element in the array. That’s all, no other magic there
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I'm not sure if you are saying I "need to get known" or you are saying I "need to learn about" what you are listing.. but my friend, I think we are talking about the same things.
@mohamedabdelkefi9947
@mohamedabdelkefi9947 2 жыл бұрын
thank you you saved my day
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Glad I could help, Mohamed! 💯
@ScriptRaccoon
@ScriptRaccoon 3 жыл бұрын
I really like the concurrent version since it is faster. When we care about the order of posts, we could just sort them after we have fetched them, right? I am not sure though if this is still faster than the serialized version then, it probably depends on the number of posts we fetch.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Nailed it here. It's going to depend on the number fetched and if you are adding the results to specific serialized data after receiving it. Several considerations. 💯
@Ginold
@Ginold 2 жыл бұрын
i did not understand WHY a forEach loop does not allow for async promise whereas for loop does?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I don't know if I can explain it here better than the video, but forEach wasn't really designed for promises. It does not wait on them to fulfill or reject. I show some alternatives in this video that will await the response and allow you to keep the results serialized.
@atgaming263
@atgaming263 2 жыл бұрын
This forEach problem was only in JS or in all programming language that has forEach function ?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I cannot speak to all programming languages, but in JS when you need to have serialized requests & responses, this provides some alternatives.
@debjyotibanerjee9846
@debjyotibanerjee9846 2 жыл бұрын
Wonderful video..
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you! 💯
@TheYinyangman
@TheYinyangman 2 жыл бұрын
Why do the higher order array methods not always return serialised data ?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Specifically, this applies to responses you await with async code. Some of the higher order methods are not designed to await responses. For example, forEach has no return. The response is not guaranteed to come back in the order the request was sent either. Some of the alternatives presented here help keep the responses received in order.
@autobot021
@autobot021 2 жыл бұрын
the promise.all method does not seem to work for me
@VirtualDarKness
@VirtualDarKness 2 жыл бұрын
In the reduce, isn't the accumulator always the initial value without a return?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Been awhile since I looked at this tutorial, but I remember another discussion in the comments along these lines. Reference here, too: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
@VirtualDarKness
@VirtualDarKness 2 жыл бұрын
@@DaveGrayTeachesCode thanks! And very interesting video
@VirtualDarKness
@VirtualDarKness 2 жыл бұрын
@@DaveGrayTeachesCode ok I understood what I was missing... Because the function is async it does of course return a promise, not undefined 😅
@Jay-dq5mq
@Jay-dq5mq 2 жыл бұрын
why not consider using bluebird.map() instead?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I provided some alternatives in the video, but not all alternatives. If used correctly, map() will work. So will reduce(), flatMap(), and reduceRight().
@johnmcaulay4348
@johnmcaulay4348 2 жыл бұрын
Hey Dave! Quick question about this. I have a situation where I need to loop through asynchronous calls to an API and the next API call depends on the value of a property from the previous API call in the loop. Is my best bet here just a regular for loop with awaits? That's how I currently have it working, but it seems a little dirty.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good question, John and that's the focus of this tutorial. I think the solution provided here that is easiest for all to understand is the for...of loop. The reduce solution also works as shown, but it may be a little more difficult for everyone to understand. Either will work! 💯
@johnmcaulay4348
@johnmcaulay4348 2 жыл бұрын
@@DaveGrayTeachesCode yeah I need to go back through the reduce solution, it went over my head a little. I'm constantly surprised by the possibilities of reduce. Thanks for the reply!
@Dibakash
@Dibakash 2 жыл бұрын
Amazing.
@alexalannunes
@alexalannunes 2 жыл бұрын
Fantastic🥳🥳🥳🥳
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you! 💯
@marufnajm7453
@marufnajm7453 2 жыл бұрын
Very interesting
@dheerajs2838
@dheerajs2838 2 жыл бұрын
this was agreat tutorial .. impressive
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you! 🙏💯
@AK-vx4dy
@AK-vx4dy 2 жыл бұрын
Sorry to say but initial example is bad or badly explained forEach executes in order, but every call lives it's own live and results come randomly from api call, it's not bad it is how it works (but maybe it is hard to understand) forEach don't wait because its job is iterate over elements not wait to execute all calls.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're saying the same thing I demonstrated. I don't expect everyone to like my explanations, no worries.
@zimcoder
@zimcoder Жыл бұрын
3:27 the fact that he has to explain it, means it is not easily readable code. Just keep it simple and readable.
Callbacks, Promises, Async Await | JavaScript Fetch API Explained
1:05:05
龟兔赛跑:好可爱的小乌龟#short #angel #clown
01:00
Super Beauty team
Рет қаралды 125 МЛН
Triple kill😹
00:18
GG Animation
Рет қаралды 17 МЛН
MAGIC TIME ​⁠@Whoispelagheya
00:28
MasomkaMagic
Рет қаралды 38 МЛН
JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue
12:35
You Probably Haven't Used This JavaScript Loop
9:36
dcode
Рет қаралды 3,2 М.
Shallow Copy and Deep Copy | Advanced Javascript Tutorial
26:36
JavaScript Pro Tips - Code This, NOT That
12:37
Fireship
Рет қаралды 2,5 МЛН
The Dangers Of Promise.all()
6:15
Theo - t3․gg
Рет қаралды 68 М.
Tips For Using Async/Await in JavaScript
16:26
James Q Quick
Рет қаралды 396 М.
The Hidden Cost Of GraphQL And NodeJS
28:35
ThePrimeTime
Рет қаралды 196 М.
5 JavaScript Concepts You HAVE TO KNOW
9:38
James Q Quick
Рет қаралды 1,4 МЛН
龟兔赛跑:好可爱的小乌龟#short #angel #clown
01:00
Super Beauty team
Рет қаралды 125 МЛН