Home > Article > Web Front-end > Why is Promise.all resolving with an array of undefined values when using async functions within a map?
Promises provide an asynchronous programming model, enabling improved code readability and flow control. However, sometimes, unanticipated issues arise. This question explores why a Promise.all is returning an array of undefined and resolving prematurely.
The code in question follows a typical promise-chaining pattern:
<code class="javascript">const getQueries = (models, dbId, dateStart, dateEnd) => { return new Promise((resolve, reject) => { // Fetch database and perform operations .then(extractQueries, reject) .then(sortQueries, reject) .then(onlyTen, reject) .then(addText, reject) .then((queries) => { console.log("getQueries finished", queries); resolve(queries); }, reject); }); };</code>
After successfully completing the initial operations, the issue arises within the addText function:
<code class="javascript">const addText = (queries) => { return Promise.all(queries.map((query) => { // Oops! We're missing a `return` here! models.queries.findById(query.queryId, { raw: true, attributes: ["query"], }) .then((queryFetched) => { query.text = queryFetched.query; console.log(query); return Promise.resolve(query); }, (error) => { return Promise.reject(error); }); })); };</code>
The root cause of the problem lies in the missing return statement in the map callback function. Promise.all expects an array of Promise objects, but without the return, the callback returns undefined for each element in the queries array.
As a result, Promise.all immediately resolves with an array of undefined, even before the actual Promises inside the map have a chance to resolve. This premature resolution leads to the unexpected behavior and an array of undefined values.
To rectify the issue, it's crucial to add the return statement before each Promise invocation in the addText function:
<code class="javascript">const addText = (queries) => { return Promise.all(queries.map((query) => { return models.queries.findById(query.queryId, { raw: true, attributes: ["query"], }) .then((queryFetched) => { query.text = queryFetched.query; console.log(query); return Promise.resolve(query); }, (error) => { return Promise.reject(error); }); })); };</code>
Now, Promise.all will correctly wait for all Promises in the array to resolve, resulting in the expected output containing the query results.
The above is the detailed content of Why is Promise.all resolving with an array of undefined values when using async functions within a map?. For more information, please follow other related articles on the PHP Chinese website!