execute a function against array items in sequence
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
To execute a function against array items in sequence (where each operation completes before the next starts), use for...of with await in JavaScript. Unlike Promise.all (which runs concurrently) or .forEach (which does not await async callbacks), a for...of loop processes one item at a time. For synchronous operations, reduce, forEach, or plain for loops all work. For async operations, only for...of with await or reduce with await guarantee sequential execution.
Synchronous Sequential Execution
for...of Loop
forEach
reduce (Accumulating Results)
Async Sequential Execution
for...of with await (Recommended)
Each await pauses the loop until the async operation completes, then moves to the next item.
reduce with await
Each iteration awaits the previous Promise before starting. The accumulator is a Promise chain that builds up the results array.
for Loop (Index-Based)
Use a traditional for loop when you need the index for progress reporting or to reference adjacent elements.
Why forEach Does NOT Work for Async
forEach ignores the return value of its callback. Since an async callback returns a Promise, forEach fires all callbacks immediately without waiting. The function exits before any fetch completes.
Sequential vs Concurrent vs Batched
Use sequential execution when:
- Each operation depends on the previous result
- You need to respect API rate limits
- Order of side effects matters (e.g., database writes)
Pipeline Pattern
Other Languages
Python
C#
Common Pitfalls
- Using
.map()for sequential async:items.map(async item => await process(item))creates an array of Promises that all start immediately. Usefor...offor true sequential execution, orPromise.all(items.map(...))for intentional concurrency. - forEach with async callbacks:
forEachdoes not await async callbacks. The enclosing function continues immediately. This is the most common mistake when trying to process items sequentially. - Forgetting error handling in loops: If one item fails in a
for...ofloop, the remaining items are skipped. Wrap the body intry/catchif you want to continue processing despite errors. - Reduce with async is hard to read: While
reduceworks for async sequential execution, it is harder to understand thanfor...of. Preferfor...offor async code and reservereducefor synchronous accumulation. - Performance with large arrays: Sequential execution of N async operations takes the sum of all operation times. If operations are independent, consider concurrent (
Promise.all) or batched execution for better throughput.
Summary
- Use
for...ofwithawaitfor async sequential execution — it is the clearest pattern forEachdoes not await async callbacks — it fires all callbacks immediately- Use
reducefor synchronous accumulation or functional pipeline composition Promise.allruns concurrently, not sequentially — use it when order does not matter- For rate-limited APIs, use sequential or batched processing
- Wrap loop bodies in
try/catchif individual failures should not stop processing
Related reading
- Executing frozen tensorflow graph that uses tensorflow.contrib.resampler using c_api.h
- Expanding tuples into arguments
- Expiry Policy on Off Heap entries not working as expected in Ignite
- Explain how recursion works in an algorithm to determine depth of binary tree?
- Execute web service method and return immediately
- Executing tasks in parallel
- Expressjs multiple threads
- Extracting an attribute value with beautifulsoup

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.