# Using Async / Await with the Array Reduce Method API (ok)

<https://github.com/typicode/json-server> <https://jsonplaceholder.typicode.com/posts?q=quasi>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FUSjomvYn1ghFUduJ7qa6%2Fimage.png?alt=media&#x26;token=8d9b5828-3ec8-4c59-9262-9f7d74ce81cd" alt=""><figcaption></figcaption></figure>

D:\Tiah\working\MARUNO-21\test.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/dayjs.min.js"></script>
</head>
<body>
  <script>
  const fetchJobs = async () => {
    const searhs = ['quasi'];
    return await searhs.reduce(async (jobsAccumulator, searh) => {
      const jobPostingsCall = await fetch(`https://jsonplaceholder.typicode.com/posts?q=${searh}`);
      const jobPostings = await jobPostingsCall.json();
      jobsAccumulator.push({
        searh,
        jobPostings,
      });
      return jobsAccumulator;
    }, []);
  }
  fetchJobs().then(function(job){
  	console.log(job);
  })
  </script>
</body>
</html>
```

## [How to use async functions with Array.reduce in Javascript](https://advancedweb.hu/how-to-use-async-functions-with-array-reduce-in-javascript/)

### How to use Promises with reduce and how to choose between serial and parallel processing

![](https://advancedweb.hu/assets/9bdfe7-98ee7a7f2f8d6a3bb3e2f5d8abd70f448dd741666e9fc8972e562654a48817d1.jpg)![Author's image](https://advancedweb.hu/assets/abc8ac-0257683b0d685aac9849920874ffa93d51f48f25f8b5f921fa8abb12c7b1c456.jpg)Tamás Sallai3 mins

This article is part of a series on Asynchronous array functions in Javascript

1. [Asynchronous array functions in Javascript](https://advancedweb.hu/asynchronous-array-functions-in-javascript/)
2. How to use async functions with Array.reduce in Javascript
3. [How to use async functions with Array.map in Javascript](https://advancedweb.hu/how-to-use-async-functions-with-array-map-in-javascript/)
4. [How to use async functions with Array.forEach in Javascript](https://advancedweb.hu/how-to-use-async-functions-with-array-foreach-in-javascript/)
5. [How to use async functions with Array.filter in Javascript](https://advancedweb.hu/how-to-use-async-functions-with-array-filter-in-javascript/)
6. [How to use async functions with Array.some and every in Javascript](https://advancedweb.hu/how-to-use-async-functions-with-array-some-and-every-in-javascript/)

[![](https://advancedweb.hu/assets/ff184b-6ff0af9d3a007a1eacc812cf13de0b4b48cb8498a9b8739c5260b5aeb700274e.png) An example is available on GistRun](https://gist.run/?id=13c59ba3b3b993935465cf8a71a2e268)

In the [first article](https://advancedweb.hu/asynchronous-array-functions-in-javascript/), we’ve covered how async/await helps with async *commands* but it offers little help when it comes to asynchronously processing *collections*. In this post, we’ll look into the `reduce` function, which is the most versatile collection function as it can emulate all the other ones.

Related[![](https://advancedweb.hu/assets/edf323-5b93755ab4596cafc605013f5d8b1dfa997d895aff4e14071b7cbf5f5120d628.jpg)](https://advancedweb.hu/asynchronous-array-functions-in-javascript/)[Asynchronous array functions in Javascript](https://advancedweb.hu/asynchronous-array-functions-in-javascript/)Array#Extras meet async/await

### The `reduce` function <a href="#the-reduce-function" id="the-reduce-function"></a>

Reduce iteratively constructs a value and returns it, which is not necessarily a collection. That’s where the name comes from, as it *reduces* a collection to a value.

The iteratee function gets the previous result, called `memo` in the examples below, and the current value, `e`.

Free email list[Weekly JS Tips - One short article about Javascript & WebDev every week](https://thecompetentdev.com/weeklyjstips/)

The following function sums the elements, starting with 0 (the second argument of `reduce`):

```
const arr = [1, 2, 3];

const syncRes = arr.reduce((memo, e) => {
	return memo + e;
}, 0);

console.log(syncRes);
// 6
```

| `memo`      | `e`   | result         |
| ----------- | ----- | -------------- |
| 0 (initial) | **1** | 1              |
| 1           | **2** | 3              |
| 3           | **3** | (end result) 6 |

&#x20;

![](https://advancedweb.hu/assets/1a8ea3a19b1e3885697e0cf6e60cad748f6244a4e3b8dc9e339335a68702f2d0.svg)

### Asynchronous `reduce` <a href="#asynchronous-reduce" id="asynchronous-reduce"></a>

An async version is almost the same, but it returns a Promise on each iteration, so `memo` will be the *Promise* of the previous result. The iteratee function needs to `await` it in order to calculate the next result:

```
// utility function for sleeping
const sleep = (n) => new Promise((res) => setTimeout(res, n));

const arr = [1, 2, 3];

const asyncRes = await arr.reduce(async (memo, e) => {
	await sleep(10);
	return (await memo) + e;
}, 0);

console.log(asyncRes);
// 6
```

| `memo`      | `e`   | result                  |
| ----------- | ----- | ----------------------- |
| 0 (initial) | **1** | Promise(1)              |
| Promise(1)  | **2** | Promise(3)              |
| Promise(3)  | **3** | (end result) Promise(6) |

&#x20;

![](https://advancedweb.hu/assets/26ceeaaaf4835ee6f00a835e2ee71b7f3f13bd4206696152c8b7353fe985ddf3.svg)

With the structure of `async (memo, e) => await memo`, the `reduce` can handle any async functions and it can be `await`ed.

### Timing <a href="#timing" id="timing"></a>

Concurrency has an interesting property when it comes to `reduce`. In the synchronous version, elements are processed one-by-one, which is not surprising as they rely on the *previous* result. But when an async `reduce` is run, all the iteratee functions start running in parallel and wait for the previous result (`await memo`) only when needed.

#### `await memo` last <a href="#await-memo-last" id="await-memo-last"></a>

In the example above, all the `sleep`s happen in parallel, as the `await memo`, which makes the function to wait for the previous one to finish, comes later.

```
const arr = [1, 2, 3];

const startTime = new Date().getTime();

const asyncRes = await arr.reduce(async (memo, e) => {
	await sleep(10);
	return (await memo) + e;
}, 0);

console.log(`Took ${new Date().getTime() - startTime} ms`);
// Took 11-13 ms
```

![](https://advancedweb.hu/assets/e4ae836b61a5646ac8fc3d0f57cd34b60eb8b65b6ddf77eeb31e63154c9c47d1.svg)

#### `await memo` first <a href="#await-memo-first" id="await-memo-first"></a>

But when the `await memo` comes first, the functions run sequentially:

```
const arr = [1, 2, 3];

const startTime = new Date().getTime();

const asyncRes = await arr.reduce(async (memo, e) => {
	await memo;
	await sleep(10);
	return (await memo) + e;
}, 0);

console.log(`Took ${new Date().getTime() - startTime} ms`);
// Took 36-38 ms
```

![](https://advancedweb.hu/assets/2e1d32b9d6345fe1443710e9a753dfefda6a1ce04fb7583f29b728179d937407.svg)

This behavior is usually not a problem as it naturally means everything that is not dependent on the previous result will be calculated immediately, and only the dependent parts are waiting for the previous value.

#### When parallelism matters <a href="#when-parallelism-matters" id="when-parallelism-matters"></a>

But in some cases, it might be unfeasible to do something ahead of time.

For example, I had a piece of code that prints different PDFs and concatenates them into one single file using the [pdf-lib](https://www.npmjs.com/package/pdf-lib) library.

This implementation runs the resource-intensive `printPDF` function in parallel:

```
const result = await printingPages.reduce(async (memo, page) => {
	const pdf = await PDFDocument.load(await printPDF(page));

	const pdfDoc = await memo;

	(await pdfDoc.copyPages(pdf, pdf.getPageIndices()))
		.forEach((page) => pdfDoc.addPage(page));

	return pdfDoc;

}, PDFDocument.create());
```

I noticed that when I have many pages to print, it would consume too much memory and slow down the overall process.

A simple change made the `printPDF` calls wait for the previous one to finish:

```
const result = await printingPages.reduce(async (memo, page) => {
	const pdfDoc = await memo;

	const pdf = await PDFDocument.load(await printPDF(page));

	(await pdfDoc.copyPages(pdf, pdf.getPageIndices()))
		.forEach((page) => pdfDoc.addPage(page));

	return pdfDoc;

}, PDFDocument.create());
```

### Conclusion <a href="#conclusion" id="conclusion"></a>

The `reduce` function is easy to convert into an async function, but parallelism can be tricky to figure out. Fortunately, it rarely breaks anything, but in some resource-intensive or rate-limited operations knowing how the functions are called is essential.
