编辑:"线程" +" async"模块不是异步(如果不是线程)安全的!它被另一个异步函数调用了!这就是为什么线程在单个异步完成之前运行它两次。有一些代码剩余部分异步调用相同的代码。
以下是一些提供错误的代码(标有ERROR!
):
async.map(threads, function (thread, cb_) {
zz++,
console.log(zz);
(function (id____) {
thread.msg({ cmd: "compare", data: id____ }, function (result) {
if (result)
compareCheck = false;
console.log(cb_.toString());
// ERROR!
cb_(null, thread); // why?
// return cb_ doesn't solve neighter
});
})(id__);
}, function (err, result) {
if (compareCheck) {
console.log("b:" + Session.cmpCtr);
threads[Session.cmpCtr % nThreads].msg({
cmd: "add", data: id__
}, function (response) {
setImmediate( cbCmp_);
});
}
else {
// whatsoever gives collision, retry new one,
// setImmediate to stop recursion fee on cpu
setImmediate(function () {
id__ = "";
for (var i = 0; i < 24; i++)
id__ += rndChar();
cmpId(id__, cbCmp_);
});
}
});
这段代码的作用是,检查N个线程(使用带有spawn的线程模块)是否在自己的列表中有一个会话变量等于新生成的会话变量然后如果没有冲突,则将新变量添加到其中一个线程名单。如果线程的命令是&#34;添加&#34;,那么它将变量添加到其列表中,如果命令是&#34;比较&#34;然后它根据列表的值和新值给出回调的真假值。
为什么async.map会出现此错误?该函数由所有线程执行,为什么不应该多次执行?这是一个回调。
也许async.map不能有一个线程列表(不可序列化),只是复制它以在每个会话变量生成时有更多的多个实例?
正在使用以下内容初始化的包装器使用线程:
threads.push(new QThread(function (input, done) {
this.data = (typeof this.data === "undefined")? [] : this.data;
if (input.cmd != null && typeof input.cmd !== "undefined") {
if (input.cmd === "add") {
data.push(input.data);
done(true);
}
else if (input.cmd === "compare")
{
for (var i = 0; i < data.length; i++) {
if (data[i] == input.data) {
done(true);
return;
}
}
done(false);
return;
}
}
}));
修改: return cb_(null, thread);
会出现同样的错误。
我想使用async.map,因为使用简单的自旋锁样式同步是cpu资源密集型的,对nodejs不利。
以下是输出错误:
C:\...\async.js:985
if (fn === null) throw new Error("Callback was already called.");
^
Error: Callback was already called.
at C:\...\async.js:985:32
at C:\...\async.js:1158:13
at C:\...\session.js:79:28
at Worker.<anonymous> (C:\...\qthread.js:25:13)
at Worker.emit (C:\...\index.js:129:35)
at Worker.handleMessage (C:\Users\pc\node_modules\threads\lib\worker.node\worker.js:119:17)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at process.nextTick (internal/child_process.js:744:12)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
答案 0 :(得分:1)
调用cb_(null, thread);
后,该函数仍然执行剩余的代码。最好终止像这样的回调
return cb_(null, thread);
这可以确保函数调用回调,停止执行并返回。