已在 async.map 中调用回调
Callback was already called in async.map
编辑: "threads"+"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 的线程模块)在它们自己的列表中是否有一个会话变量等于新生成的一个,然后如果没有冲突,则将新变量添加到其中一个线程列表。如果线程的命令是 "add",那么它将变量添加到它的列表中,如果命令是 "compare",那么它根据列表的值和新值在回调中给出真假值。
为什么 async.map 会出现这个错误?该函数由所有线程执行,为什么不应该执行多次?是回调。
也许 async.map 不能有一个线程列表(它是不可序列化的)并且只是复制它以便在每次会话变量生成时有更多的多个实例?
Threads 正被初始化为以下内容的包装器使用:
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)
调用cb_(null, thread);
后,函数仍然执行剩下的代码。最好像这样终止回调
return cb_(null, thread);
这确保函数调用回调、停止执行并returns。
编辑: "threads"+"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 的线程模块)在它们自己的列表中是否有一个会话变量等于新生成的一个,然后如果没有冲突,则将新变量添加到其中一个线程列表。如果线程的命令是 "add",那么它将变量添加到它的列表中,如果命令是 "compare",那么它根据列表的值和新值在回调中给出真假值。
为什么 async.map 会出现这个错误?该函数由所有线程执行,为什么不应该执行多次?是回调。
也许 async.map 不能有一个线程列表(它是不可序列化的)并且只是复制它以便在每次会话变量生成时有更多的多个实例?
Threads 正被初始化为以下内容的包装器使用:
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)
调用cb_(null, thread);
后,函数仍然执行剩下的代码。最好像这样终止回调
return cb_(null, thread);
这确保函数调用回调、停止执行并returns。