使用Bluebird的Promise.map未等待全部任务完成,求解决方案?
Hey there! Let's break down why your "Done" log is showing up before your fetch and render steps finish, and fix your Promise.map usage for good.
The Root Problem
Right now, your iteration function inside Promise.map isn't returning a Promise. Bluebird's Promise.map relies on each item in the array returning a Promise to know when that item's async work is done. Since you're not returning the fetch/render Promise, Promise.map thinks all items are processed immediately and jumps straight to the .then() block.
Corrected & Optimized Implementation
First, let's clean up the parameter name (using the same name as your array is confusing!) and make sure every async step returns a Promise:
// Assume fetchPostFromDatabase is your async DB call that returns a Promise // Assume renderPost is your post-rendering function (async if needed) Promise.map(data_array, function(postId) { // Return the entire Promise chain so Promise.map waits for it return fetchPostFromDatabase(postId) .then(function(post) { // If rendering is async, return that Promise too return renderPost(post); }) .then(function() { console.log("after process"); }); }) .then(function() { console.log("Done"); }) .catch(function(error) { // Always add error handling to catch failed DB calls/renders! console.error("Something went wrong processing posts:", error); });
Key Improvements
- Return Promises: Every async operation's Promise is returned, so
Promise.mapwaits for all items to finish before resolving. - Cleaner Parameter Naming: Changed
data_arraytopostIdinside the iteration function to avoid confusion with your original array. - Error Handling: Added a
.catch()block to catch any failed database requests or rendering issues—critical for debugging!
Even More Concise (Arrow Function) Version
If you prefer modern syntax, you can shorten this up:
Promise.map(data_array, postId => fetchPostFromDatabase(postId) .then(renderPost) .then(() => console.log("after process")) ) .then(() => console.log("Done")) .catch(err => console.error("Error processing posts:", err));
With this setup, "Done" will only log once every post has been fetched from the database, rendered, and "after process" has been logged for each item.
内容的提问来源于stack exchange,提问作者Caitlin Wen

