caolan / async

Async utilities for node and the browser
http://caolan.github.io/async/
MIT License
28.15k stars 2.41k forks source link

async.eachSeries with TypeScript gets stuck on first element in the collection #1971

Closed JonathanHolvey closed 2 months ago

JonathanHolvey commented 2 months ago

tl;dr

async.eachSeries and similar functions fail with TypeScript pollyfilled Promises. Only the first element in the collection is processed, and the loop never finishes. Setting the TypeScript compilerOptions.target config option to ES2017 or later resolves the issue.

Problem

What version of async are you using? v3.2.5

Which environment did the issue occur in (Node/browser/Babel/Typescript version) Node

What did you do? Please include a minimal reproducible case illustrating issue.

index.ts

import async from 'async'

async.eachSeries(['a', 'b', 'c'], async (item: string) => {
  await Promise.resolve() // Something to do
  console.log(item)
})

tsconfig.json

{
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": ".",
    "module": "NodeNext",
    "target": "ES6",
  }
}

Build and run the script:

tsc && node dist/index.js

What did you expect to happen?

Output should be:

a
b
c

What was the actual result?

The promise from the first iteration of the loop never resolves, and the actual output is:

a

Solution

This issue is caused by the pollyfilled Promise implementation that TypeScript provides for the ES6 output target. Changing the target to ES2017 or later allows the use of native promises, which work as expected with the async library.

JonathanHolvey commented 2 months ago

Just posting this in case anyone runs into the same issue.

dandean commented 1 month ago

@JonathanHolvey – thank you for sharing this. It helped our team figure out what was going on in our own codebase.