NodeJS:多个回调执行完毕后触发指定回调的实现方案
Hey, great question! You’re already on the right track with using a counter—let’s refine that idea to make it work reliably, plus I’ll show you a more modern approach that’s cleaner and less error-prone.
Option 1: Manual Counter Approach (Your Original Idea)
The core idea here is to track how many async callbacks have finished, and trigger your target callback only when all of them are done. Here’s how to implement it properly:
function myFunc(ID, callback) { // Initialize counter to the number of async functions we need to wait for let completedTasks = 3; // Helper function to check if all tasks are done function checkIfAllDone() { completedTasks--; // When counter hits 0, all callbacks have executed if (completedTasks === 0) { callback("something"); // Replace "something" with your desired value } } // Call each async function, and run our helper after their own callback logic func1("foo", res => { console.log(res); checkIfAllDone(); }); func2("bar", res => { console.log(res); checkIfAllDone(); }); func3("batz", res => { console.log(res); checkIfAllDone(); }); }
Key Notes:
- The
completedTaskscounter starts at 3 (one for each async function). - Every time an async callback finishes its own work (like
console.log(res)), it callscheckIfAllDone()to decrement the counter. - When the counter reaches 0, we know all three callbacks have run—so we trigger your target
callback.
Option 2: Modern Promise-Based Approach (Cleaner & More Maintainable)
If you’re open to using Promises (which are standard in modern JavaScript), this approach avoids manual counter management entirely and is easier to read:
First, we’ll wrap your callback-style functions into Promises, then use Promise.all() to wait for all of them to complete:
// Helper function to convert callback-style functions to Promises function promisifyAsyncFunc(func, arg) { return new Promise(resolve => { func(arg, res => { console.log(res); resolve(res); // Pass the result to the Promise }); }); } function myFunc(ID, callback) { // Run all three async functions as Promises Promise.all([ promisifyAsyncFunc(func1, "foo"), promisifyAsyncFunc(func2, "bar"), promisifyAsyncFunc(func3, "batz") ]) .then(allResults => { // All async callbacks have finished—call your target callback callback(allResults); // Or callback("something") if you don't need results }); }
Why This Works:
Promise.all()waits until every Promise in the array resolves (i.e., every async function’s callback has run).- The
.then()block only executes once all three tasks are done, so you can safely call yourcallbackhere. - This approach is less error-prone than manual counters (no risk of forgetting to decrement the counter, or off-by-one errors).
Bonus: Collecting Results from All Async Functions
If you need to pass the results of func1, func2, and func3 to your target callback, both approaches can be modified to collect those values:
Counter Approach with Results:
function myFunc(ID, callback) { let completedTasks = 3; const results = []; function checkIfAllDone() { completedTasks--; if (completedTasks === 0) { callback(results); // Pass collected results to callback } } func1("foo", res => { console.log(res); results.push(res); checkIfAllDone(); }); func2("bar", res => { console.log(res); results.push(res); checkIfAllDone(); }); func3("batz", res => { console.log(res); results.push(res); checkIfAllDone(); }); }
Promise Approach with Results:
The Promise version already collects results automatically—allResults in the .then() block will be an array with the results of func1, func2, func3 in order.
内容的提问来源于stack exchange,提问作者Morgan Le Floc'h

