Node.js使用async.parallel练习代码遇callback未定义错误求助
Hey there! Let's break down why you're hitting that "callback is undefined" error and get your async.parallel code working as expected.
What's Causing the Error?
First, the main issue: async.parallel expects each task in your list to be a function that accepts a callback parameter. Right now, your doSomething function tries to call callback immediately, but no callback is being passed to it—hence the "undefined" error.
There's also a sneaky secondary problem: you're reusing the same tempjson object across all loops. Since objects are reference types, every task will end up modifying and returning the same object, so all your final results will show the last values of i and j instead of the intended ones.
Fixed Code
Let's rewrite your code to fix both issues:
const async = require('async'); // Don't forget to require the async module! var tasklist = []; for(var i = 0; i < 10; i++) { // Create a new tempjson object in each i-loop to avoid reference sharing var tempjson = { data: 'i is ' + i }; for(var j = 0; j < 20; j++){ tasklist.push(doSomething(tempjson, j)); } } // Fixed variable name: tasklist (not taskList) — JavaScript is case-sensitive! async.parallel(tasklist, function(err, data) { if (err) { console.error('Error occurred:', err); return; } console.log(data); }); // Rewrite doSomething to return a function that accepts the async callback function doSomething(params, j){ // Return a closure that captures params and j for each task return function(callback) { // Create a copy of params to avoid mutating the original object (safer practice) const result = {...params}; result.data2 = 'j value is ' + j; // Call the async callback to signal task completion callback(null, result); } }
Key Fixes Explained
- Proper Callback Handling:
doSomethingnow returns a function that takes thecallbackparameter provided byasync.parallel. This lets you properly signal when the task is done and pass the result back to the async library. - Avoid Reference Sharing: By creating a new
tempjsoninside each iteration of theiloop, we ensure each task gets its own unique object instead of all sharing the same one. We also make a copy ofparamsinside the closure to prevent unintended mutations. - Variable Name Consistency: Fixed the typo where you used
tasklistandtaskList(case mismatch)—a common gotcha in JavaScript!
Bonus: Modern Alternative with Async/Await (Optional)
If you're working with a newer Node.js version, you might prefer using Promise.all with async/await for more readable code (no need for the async library):
async function runTasks() { var tasklist = []; for(var i = 0; i < 10; i++) { var tempjson = { data: 'i is ' + i }; for(var j = 0; j < 20; j++){ // Wrap each operation in a promise tasklist.push(new Promise((resolve) => { const result = {...tempjson}; result.data2 = 'j value is ' + j; resolve(result); })); } } const data = await Promise.all(tasklist); console.log(data); } runTasks();
内容的提问来源于stack exchange,提问作者Dexter




