5

I have a function that returns a Promise like this:

async function processFolder(folder) {
    return new Promise(async (res) => {
        const table = {};
        const list = await getHTMLlist(folder);
        if (list.length === 0) res(table);
        for (let i = 0; i < list.length; i++) {
            await processFile(folder, list[i], table);
        }
        res(table);
    });
}

I'm using ESLint that warn me:

"Promise executor functions should not be async" that is the no-async-promise-executor rule that throw an error due to the async keyword in the Promise declaration.

I have already fixed the same problem in other parts of the code where there was only one await inside the Promise using the technique suggested on this page of the ESLint documentation and showed in this answer, but in my use case I don't really know how to refactor the code in order to avoid that error. Any suggestions are welcome

Plastic
  • 9,874
  • 6
  • 32
  • 53
  • 1
    Why have you wrapped `await getHTMLlist(folder)` and `await processFile(folder, list[i], table);` with a promise constructor? `async` function already returns a promise so you don't need to create a new one and return it – Yousaf Oct 07 '20 at 14:50
  • The function reads and parse a given folder looping through all files inside the folder collecting some data that will be stored inside the object "table". The promise is fullfilled as every files in the folder has been read. The promise is then resolved passing "table" as argument – Plastic Oct 07 '20 at 14:54
  • Does this answer your question? [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – Lux Oct 07 '20 at 15:36
  • @Lux unfortunately no, I know that question, I read it and applied the answer to different use cases in my code, in this case however I had to deal with several awaits inside the Promise, some of them generated in a loop. The answer was simple but unrelated to that question – Plastic Oct 07 '20 at 15:50

1 Answers1

14

You don't need to create a new promise yourself because async functions always return a promise. If the return value of an async function is not a promise, it is implicitly wrapped in a promise.

So you need to remove the code that creates a new promise instance and the code inside the executor function should be at the top-level in the processFolder function.

Your code can be simplified as shown below:

async function processFolder(folder) {
    const table = {};
    const list = await getHTMLlist(folder);

    if (list.length > 0) {
       for (let i = 0; i < list.length; i++) {
           await processFile(folder, list[i], table);
       }
    }

    return table;
}

Ideally, you should also wrap the code inside the processFolder function in a try-catch block to catch and handle any errors that might occur during the execution of this function.

Yousaf
  • 27,861
  • 6
  • 44
  • 69
  • 3
    In addition to `return` resolving the async function's promise, you can use `throw` to reject it. – lexical Jan 08 '22 at 15:35