我收到了'已经使用过的回调'错误,我不知道为什么。我正在使用异步并希望链接两个函数,因为第二个函数依赖于要完成的第一个函数。
我是Node.js的新手,仍然围绕着异步/回调。非常感谢你帮忙。
getCdn接受cnames,如果cname是CDN的一部分,它会将结果推送到名为cdnAttrs的全局变量中。
function getCdn(cnameDict, callback) {
// cdnAttributes contains associative array with each web attribute: {name_in_db : code_snippet_to_find_in_cname}
for (var key in cdnAttributes) {
if (cdnAttributes.hasOwnProperty(key)) {
var snippet = -1;
// some technologies contain multiple code snippets, in that case they are stored as array. Single code snippets are stored as string
if (!Array.isArray(cdnAttributes[key])) {
snippet = cnameDict['cname'].indexOf(cdnAttributes[key])
}
else {
// check each code snippet within the array, if any match the source code, update 'snippet'
for (var n = 0; n < cdnAttributes[key].length; n++) {
var val = cnameDict['cname'].indexOf(cdnAttributes[key][n])
if (val > -1) {
snippet = val
}
}
}
// if attribute found in tag, create cdnAttrs[cdn] = [{from: hostname, proof: cname}, {from: hostname2, proof: cname2}, ...]
if (snippet > -1) {
try {
cdnAttrs[key].push(cnameDict);
}
catch (e) {
cdnAttrs[key] = [];
cdnAttrs[key].push(cnameDict);
}
callback();
} else {
callback();
}
} else {
callback();
}
}
}
我的异步功能如下所示:
async.series([
// THIS FUNCTION WORKS FINE...
function(callback) {
async.each(toCheck, function(hostname, callback) {
getCname(hostname, callback);
},callback);
},
// THIS FUNCTION RETURNS RETURNS Error("Callback was already called.")
function(callback) {
async.each(toCheckCnames, function(cnameDict, callback) {
getCdn(cnameDict, callback);
},callback);
}
], function(err){
if(err) {
console.log('ERROR');
}else{
console.log('toCheckCnames is done: '+JSON.stringify(toCheckCnames));
console.log('cdnAttrs is done: '+JSON.stringify(cdnAttrs));
}
})
getCnames函数有效:
function getCname(hostname, callback){
dns.resolve(hostname, 'CNAME', function(error, cname) {
if (cname) {
toCheckCnames.push({from: hostname, cname: cname[0]});
callback();
}
// if not CNAMEd, check SOA on www.domain.com and domain.com
else {
if (hostname.slice(0,4) == 'www.') {
hostname = hostname.slice(4);
}
nativedns.resolve(hostname, 'SOA', function(error, records) {
if(!error && records) {
toCheckCnames.push({from: hostname, cname: records[0]['primary']});
callback();
}
else if (!error) {
hostname = 'www.'+ hostname
nativedns.resolve(hostname, 'SOA', function(error, records) {
if (!error) {
toCheckCnames.push({from: hostname, cname: records[0]['primary']});
callback();
}
else callback()
});
}
else callback()
});
}
});
}
答案 0 :(得分:1)
您的getCdn
函数是一个循环,它将在每次迭代后调用回调。如果调用回调旨在停止循环执行,则可以执行return callback()
。否则,您需要重新组织代码,以便仅在函数完成时调用一次回调。
更新:
您还可以简化async.each调用:
// Was this
async.each(toCheck, function(hostname, callback) {
getCname(hostname, callback);
},callback);
// Could be this
async.each(toCheck, getCname, callback);