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
@ocoolsanni28032 жыл бұрын
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??
@DaveGrayTeachesCode2 жыл бұрын
@@ocoolsanni2803 I'm not sure how this applies to web scraping. You can use an interval in JS to time the requests if needed.
@ocoolsanni28032 жыл бұрын
@@DaveGrayTeachesCode Thanks for the quick responce and guidence, in an api i'm working on. Looking foward to a scrapping tutorial from you
@Gameplayer550552 жыл бұрын
replacing foreach with for helped dramatically, now my entries don't hang page for 4 seconds
@hasithadhananjaya28062 жыл бұрын
dear sir, I'm begginer for JS, what is the frame work I should learn first NODE or REACT or else. Please!.
@Bayo1063 жыл бұрын
as soon as I saw this title I had an epiphany and watching it helped me solve something at work. thank you so much
@DaveGrayTeachesCode3 жыл бұрын
That's great to hear! 💯
@cedigasser2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Agreed as discussed in a few of the other comments. 💯
@absbica312 жыл бұрын
@@DaveGrayTeachesCode does this mean line 25 at the end?
@Cerbeh3 жыл бұрын
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!
@DaveGrayTeachesCode3 жыл бұрын
And you just described a great use case! Nice! 💯🚀
@maestrocode91642 жыл бұрын
Would a for-of loop do the same? I fail to see the difference
@DaveGrayTeachesCode2 жыл бұрын
@@maestrocode9164 if you watch the video you will see the for of loop demonstrated as well.
@glennadams88333 жыл бұрын
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!
@DaveGrayTeachesCode3 жыл бұрын
Glad it helped Glenn 💯
@NguyenNguyen-ek4zq2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Good note! 💯
@benarcher3723 жыл бұрын
"To get the job done". Most of the time that's all that matters. Thank you Dave for all your great JavaScript tutorials.
@DaveGrayTeachesCode3 жыл бұрын
You're welcome 🙏💯
@takahiro01272 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Thank you for the kind words, Chris 🙏 You're welcome! 💯
@lalitpatil79722 жыл бұрын
2 days before I was struggling with this forEach with async issue and today I saw your video. Saved my day. Thank you.
@DaveGrayTeachesCode2 жыл бұрын
Glad it helped! 💯
@pellax2 жыл бұрын
Trying to improve my Javascript, great video, subscribed
@DaveGrayTeachesCode2 жыл бұрын
Thank you! 💯
@dweblinveltz50352 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Great comment, Dweblin! 💯
@quinndirks56532 жыл бұрын
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 Жыл бұрын
Reduce is so versatile, can do a million things with it. This was really neat
@DebdutBiswasOnline2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Glad I could help! 💯
@caffeinated-pixels3 жыл бұрын
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.
@DaveGrayTeachesCode3 жыл бұрын
Right on 💯
@AntonioSantos-ve6zv2 жыл бұрын
Kind of advanced for me at this point, but it's put so clearly I've learned a lot. Thanks!
@DaveGrayTeachesCode2 жыл бұрын
You're welcome, Antonio! 💯
@yadusolparterre2 жыл бұрын
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
@DaveGrayTeachesCode2 жыл бұрын
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 Жыл бұрын
dude you seem junior, go back to mdn
@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 Жыл бұрын
Glad this helped!
@urssaf3432 жыл бұрын
Let's not forget "for await... of" loops and "generators" solution.
@timderks59602 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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 Жыл бұрын
Road to 500k, congrats for the 100k🎉🎉🎉🎉
@DaveGrayTeachesCode Жыл бұрын
Thank you!! 🚀
@rajapboyev39282 жыл бұрын
Big thanks to Dave Gray, very good explanation😃
@DaveGrayTeachesCode2 жыл бұрын
You're very welcome! 🙏
@samirsamir77793 жыл бұрын
Thank you Dave for this super great dev. Channel as Well as your Teaching way .
@DaveGrayTeachesCode3 жыл бұрын
You're welcome, Samir! 💯
@cas8180282 жыл бұрын
Devs care about other devs and their mental health. Please don’t ever use reduce this way. Thank you
@torinzhou26262 жыл бұрын
That’s amazing Dave! You’ve made it crystal clear! Thanks for you efforts!👏👏👏👏
@torinzhou26262 жыл бұрын
And I’m heading to your pure function video😀Have a strong feeling I would regret if I miss that one.
@DaveGrayTeachesCode2 жыл бұрын
You're welcome! 💯
@brightmatter2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
In this video, I demonstrate several alternatives that do indeed work by awaiting promises to fulfill. 💯
@kevinbatdorf2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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.
@kevinbatdorf2 жыл бұрын
@@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.
@DaveGrayTeachesCode2 жыл бұрын
@@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.
@BrianVanderbusch2 жыл бұрын
@@DaveGrayTeachesCode just look at the poster frame for this vid... It really strongly implies "don't use for each".
@DaveGrayTeachesCode2 жыл бұрын
@@BrianVanderbusch agreed. It's an attention getter and has generated a few unintended flames.
@shrooobdude2 жыл бұрын
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 :)
@DaveGrayTeachesCode2 жыл бұрын
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 😃
@shrooobdude2 жыл бұрын
@@DaveGrayTeachesCode oh no you never said Promise.all wouldn't work - just that the order may not be retained 😁
@DaveGrayTeachesCode2 жыл бұрын
@@shrooobdude ah I see! I'd like to make a separate Promise.all video as well.
@johnmcaulay43482 жыл бұрын
Learnt this one the hard way the other day, should have been paying more attention to your videos!
@DaveGrayTeachesCode2 жыл бұрын
This one is catches many by surprise. 💯
@TarekFaham2 жыл бұрын
I needed this in a project coming up soon. Thanks a lot for your help.
@DaveGrayTeachesCode2 жыл бұрын
Glad I could help!
@janjankowski87012 жыл бұрын
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_r2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Agreed, and noted in some other comment discussions, too. The array holds the order. Thanks! 🙏💯
@mohamedamineboukraia55282 жыл бұрын
What a great tutorial Dave!!
@DaveGrayTeachesCode2 жыл бұрын
Thank you, Mohamed!
@alexanderkomanov41512 жыл бұрын
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!
@DaveGrayTeachesCode2 жыл бұрын
You're welcome! 💯
@gradar78912 жыл бұрын
Most informative tutorial I’ve ever encountered for recent years 😄
@subhajitpanja13532 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Thank you for the kind words and again for the request! 🙏
@cleancode21233 жыл бұрын
Nice one learned a lot !.
@DaveGrayTeachesCode3 жыл бұрын
Glad to hear that! 💯
@0xAndy2 жыл бұрын
Thank you so much. I'm a new subscriber and really enjoy the channel so far.
@DaveGrayTeachesCode2 жыл бұрын
Welcome aboard! 🚀🚀
@jollybeancomedy2 жыл бұрын
Thank you for the video! The forEach not executing in order thing once got me into trouble, hope I had noticed it earlier.
@DaveGrayTeachesCode2 жыл бұрын
You're welcome! 💯
@manujohn53462 жыл бұрын
Wow...very helpful. Wish I had seen this few months back. Would have saved me a ton of time😅
@DaveGrayTeachesCode2 жыл бұрын
Glad I could help! 🙏
@basilistigris6403 жыл бұрын
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!
@DaveGrayTeachesCode3 жыл бұрын
Thank you for the kind words, Basilis! 🙏
@zoaybk2 жыл бұрын
map approach was the best one I think, great video thanks
@DaveGrayTeachesCode2 жыл бұрын
You're welcome! 💯
@hv74602 жыл бұрын
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...
@DaveGrayTeachesCode2 жыл бұрын
You're welcome!
@dindoleonard2 жыл бұрын
So glad i stumbled into this gold mine of a video
@DaveGrayTeachesCode2 жыл бұрын
Thank you, Leonardo! 💯
@navazsharif67832 жыл бұрын
Just came here after watching James Q Quick video that you are talking about at 11:00
@tomascarignano50022 жыл бұрын
This is amazing! Thank you for the great explanation
@DaveGrayTeachesCode2 жыл бұрын
You're very welcome! 💯
@arminmatthes2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
Good note, Armin! 💯
@arshiagholami76113 жыл бұрын
I really liked the idea of using reduce here, never seen something like this. thanks for the great vid
@DaveGrayTeachesCode3 жыл бұрын
It is an interesting use. Thanks for the comment! 💯
@TheDaviddoodles2 жыл бұрын
Hey Dave would you do some videos about Svelte I really love the way explain things
@DaveGrayTeachesCode2 жыл бұрын
Thank you for the request! It may be awhile, but I'd like to do something with Svelte, too!
@kevinbatdorf2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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!
@kevinbatdorf2 жыл бұрын
@@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.
@DaveGrayTeachesCode2 жыл бұрын
@@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.
@laurentgauthier87422 жыл бұрын
Super interesting! Thank you so much!
@DaveGrayTeachesCode2 жыл бұрын
You're welcome! 💯
@nemanjasavic985928 күн бұрын
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
@vitason1002 жыл бұрын
Hi Dave, Thank for this tutorial !!! Can you explain how we can handle error in this way, thank you.
@DaveGrayTeachesCode2 жыл бұрын
Try / catch blocks are good for handling errors 💯
@luisaugsburger3 жыл бұрын
Thanks dude! nice explanation!
@DaveGrayTeachesCode3 жыл бұрын
Glad you liked it! 🚀
@SkyrimBeast2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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.
@oksanakobyliatska68222 жыл бұрын
Thanks a lot, that was very helpful!
@DaveGrayTeachesCode2 жыл бұрын
Glad to hear that!
@PauloSantosk2 жыл бұрын
forEach respected the await instrucion, but It was executed recursively in a more performatic way. If you need order, sort the results.
@fParad0x_2 жыл бұрын
Do you have any info on how that works? I didn't know that forEach was executed in a different, special way.
@PauloSantosk2 жыл бұрын
@@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.
@BrianVanderbusch2 жыл бұрын
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_2 жыл бұрын
@@PauloSantosk Thanks for the explanation! Didn't know that.
@n1xx12 жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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.
@rike77773 жыл бұрын
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!
@DaveGrayTeachesCode3 жыл бұрын
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.
@LordValtrius2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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.
@LordValtrius2 жыл бұрын
@@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
@DaveGrayTeachesCode2 жыл бұрын
@@LordValtrius I appreciate the reply - and great share! Thank you! 💯🚀
@코린이31세3 жыл бұрын
Amazing lecture!!!! Thank you sir 👍👍
@DaveGrayTeachesCode3 жыл бұрын
You're welcome!
@polinafeterman50572 жыл бұрын
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!
@DaveGrayTeachesCode2 жыл бұрын
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.
@jiweihe34132 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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
@jiweihe34132 жыл бұрын
@@DaveGrayTeachesCode I see. That makes sense! Thank you so much!
@saitejagatadi97112 жыл бұрын
13:13 Dave, The mobile mode was on in browser. Not sure it was intentional 😄
@DaveGrayTeachesCode2 жыл бұрын
I usually have mobile mode on when I open Chrome Devtools.
@TheRishikesh992 жыл бұрын
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
@DaveGrayTeachesCode2 жыл бұрын
Agreed 💯 There is an example of using Promise.all in this video along with a few other possibilities.
@ericapinheiro98912 жыл бұрын
Amazing reducing js!
@DaveGrayTeachesCode2 жыл бұрын
Thank you, Erica! 💯
@CesarScur2 жыл бұрын
The "problem" is not with the foreach concept. It is with the closure implementation of this foreach. Foreach is not evil.
@DaveGrayTeachesCode2 жыл бұрын
Never said it was. This video is for those who try to use forEach when they want a serialized response.
@arminmatthes2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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.
@decay65912 жыл бұрын
fixed redux thunk bug. appreciate. got sub
@DaveGrayTeachesCode2 жыл бұрын
Glad I could help!
@wojciechjarosz42010 ай бұрын
...and how to return fetched and resolved data from reduce function in this case?
@melpacheco9288 Жыл бұрын
Masterful!
@randomnobody6602 жыл бұрын
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?
@randomnobody6602 жыл бұрын
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.
@randomnobody6602 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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.
@krishanlanka76592 жыл бұрын
hi, can you correct my php if statement pls
@thecutedreamkostasp.44492 жыл бұрын
Thx God there are better programmers than me. They make me bettter. I appreciate this sir.
@DaveGrayTeachesCode2 жыл бұрын
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 Жыл бұрын
Nice use of reduce!
@luiizmorales3162 жыл бұрын
thanks bro... good video 👍🏽
@DaveGrayTeachesCode2 жыл бұрын
You're welcome!
@aman75553 жыл бұрын
Awesome 👌
@DaveGrayTeachesCode3 жыл бұрын
🙏 Thank you!
@MaksymMinenko2 жыл бұрын
12:40 The white screen of death. 😀
@DM-pg4iv2 жыл бұрын
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?
@DaveGrayTeachesCode2 жыл бұрын
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 Жыл бұрын
how to break/exit the reduce loop and return the last value?
@TarekFaham2 жыл бұрын
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?
@DaveGrayTeachesCode2 жыл бұрын
I do not at this time, but it is a good idea! Thanks for your request!
@designcoded75853 жыл бұрын
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
@Shubhaw3 жыл бұрын
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?
@DaveGrayTeachesCode3 жыл бұрын
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
@Shubhaw3 жыл бұрын
@@DaveGrayTeachesCode Thanks again! :)
@tyler8995 Жыл бұрын
What's the extension that gives that line between your opening and closing braces?
@DaveGrayTeachesCode Жыл бұрын
Here you go: kzbin.infoMDaxWffMjrQ
@tyler8995 Жыл бұрын
@@DaveGrayTeachesCode thank you!
@djkos72 жыл бұрын
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
@DaveGrayTeachesCode2 жыл бұрын
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.
@mohamedabdelkefi99472 жыл бұрын
thank you you saved my day
@DaveGrayTeachesCode2 жыл бұрын
Glad I could help, Mohamed! 💯
@ScriptRaccoon3 жыл бұрын
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.
@DaveGrayTeachesCode3 жыл бұрын
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. 💯
@Ginold2 жыл бұрын
i did not understand WHY a forEach loop does not allow for async promise whereas for loop does?
@DaveGrayTeachesCode2 жыл бұрын
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.
@atgaming2632 жыл бұрын
This forEach problem was only in JS or in all programming language that has forEach function ?
@DaveGrayTeachesCode2 жыл бұрын
I cannot speak to all programming languages, but in JS when you need to have serialized requests & responses, this provides some alternatives.
@debjyotibanerjee98462 жыл бұрын
Wonderful video..
@DaveGrayTeachesCode2 жыл бұрын
Thank you! 💯
@TheYinyangman2 жыл бұрын
Why do the higher order array methods not always return serialised data ?
@DaveGrayTeachesCode2 жыл бұрын
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.
@autobot0212 жыл бұрын
the promise.all method does not seem to work for me
@VirtualDarKness2 жыл бұрын
In the reduce, isn't the accumulator always the initial value without a return?
@DaveGrayTeachesCode2 жыл бұрын
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
@VirtualDarKness2 жыл бұрын
@@DaveGrayTeachesCode thanks! And very interesting video
@VirtualDarKness2 жыл бұрын
@@DaveGrayTeachesCode ok I understood what I was missing... Because the function is async it does of course return a promise, not undefined 😅
@Jay-dq5mq2 жыл бұрын
why not consider using bluebird.map() instead?
@DaveGrayTeachesCode2 жыл бұрын
I provided some alternatives in the video, but not all alternatives. If used correctly, map() will work. So will reduce(), flatMap(), and reduceRight().
@johnmcaulay43482 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
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! 💯
@johnmcaulay43482 жыл бұрын
@@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!
@Dibakash2 жыл бұрын
Amazing.
@alexalannunes2 жыл бұрын
Fantastic🥳🥳🥳🥳
@DaveGrayTeachesCode2 жыл бұрын
Thank you! 💯
@marufnajm74532 жыл бұрын
Very interesting
@dheerajs28382 жыл бұрын
this was agreat tutorial .. impressive
@DaveGrayTeachesCode2 жыл бұрын
Thank you! 🙏💯
@AK-vx4dy2 жыл бұрын
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.
@DaveGrayTeachesCode2 жыл бұрын
You're saying the same thing I demonstrated. I don't expect everyone to like my explanations, no worries.
@zimcoder Жыл бұрын
3:27 the fact that he has to explain it, means it is not easily readable code. Just keep it simple and readable.