Node.js Patterns: Sequential Iteration Pattern

The sequential iteration pattern is best used if you have an array of elements which you want to feed into an async function.

The following example has a list of filenames.
The filenames are feeded with a foreach loop to an async function that reads out the content of the files.

The contents of the files are stored in an array and when the last task is processed the last resolved value gets passed to the last then.

file1.txt

1
This is content from file1.

file2.txt

1
This is content from file2.

sequential-iteration-promise.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*******************************************************************************
Author: Peter Forgacs <peter@sexybuddha.hu>
Description: Sequential Iteration Pattern : Promise version
********************************************************************************/

'use strict';
const fs = require('fs');
let tasks = ['file1.txt', 'file2.txt']; // A list that we want to iterate
let values = [];
let promise = Promise.resolve(); // Create a base resolved promise

/**
* Async function that gets called multiple times.
* @param {string} path - path to a file
*/
function task(path) {
return new Promise ( (resolve, reject) => {
fs.readFile( path, 'utf8', (err, data) => {
if (err) reject(err);
values.push(data); // Store the values in an array
resolve(values);
});
});
}


tasks.forEach(filename => {
/*******************************************************************************
We update the initial promise with a new one coming fron the then statement.
This is possible because then statements automatically create one.
This basically adds .then() statements one after the other.
ex: .then().then()
********************************************************************************/
promise = promise.then(() => {
return task(filename);
});
});

/*******************************************************************************
The last resolved element gets passed to this .then().
Since we are resolving the values array we get all the data from it.
********************************************************************************/
promise.then(data => {
//All tasks completed
console.log(data);
});