使用async库执行并行任务时报callback is not a function错误的原因
错误产生原因
这个报错是async库对传入的异步任务函数的格式要求和代码实现不匹配导致的,核心原因有两点:
async.parallel接收的任务函数如果是async/await形式的异步函数,async库默认不会给这类函数传入callback参数,代码里尝试调用的callback自然是undefined,触发类型错误。async库v3.x之后对Promise风格的异步函数和传统回调风格的异步函数做了明确区分:- 如果使用回调风格的普通函数(不带async关键字),库会自动注入callback参数,可通过callback传递结果/错误
- 如果使用async函数,库会直接以Promise的返回值作为任务结果,不需要也不会提供callback参数
另外额外说明:你现有代码中直接把结果值传给callback的写法也不符合规则,回调的第一个参数是错误位,传非空值会被async库判定为任务执行失败,不会进入结果集合。
修复方案
两种修改方式选一种即可:
方式1:保留async函数,去掉callback调用
const async = require("async"); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } const parallels = []; for (let i = 0; i < 2; i++) { parallels.push(async function () { const randomSleepTime = Math.ceil(Math.random() * 10000); await sleep(randomSleepTime); // 直接return值作为当前任务的结果,不需要callback return randomSleepTime; }); } async.parallel(parallels, function (err, results) { console.log(err); console.log(results); });
方式2:改用回调风格的普通函数,不用async关键字
const async = require("async"); const parallels = []; for (let i = 0; i < 2; i++) { // 去掉async关键字,作为普通回调风格函数,库会传入callback parallels.push(function (callback) { const randomSleepTime = Math.ceil(Math.random() * 10000); setTimeout(() => { // 第一个参数传null代表无错误,第二个参数为任务结果 callback(null, randomSleepTime); }, randomSleepTime) }); } async.parallel(parallels, function (err, results) { console.log(err); console.log(results); });
内容的提问来源于stack exchange,提问作者Cedric Hadjian
相关产品推荐
相关产品推荐

