How can I optimize the following NodeJS code to work in an async fashion and be fast? I imagine the stack is getting too big and it's causing the program to slow down and eventually crash. Is there a better way to resolve a big quantity of domain names from the example below?
const dns = require('dns');
const os = require('os');
var logical_cores = os.cpus().length;
console.log(`Logical cores: ${logical_cores}`);
process.env.UV_THREADPOOL_SIZE=logical_cores;
domainToIp_resolve = (domain) => {
return new Promise((resolve, reject) => {
// does not use libuv thread pool; uses os async polling
dns.resolve(domain, 'A', (err, records) => {
if (err) {
reject(`${String(domain).toUpperCase()} | ERROR CODE: ${err.code} | ERROR MESSAGE: ${err.message}`);
} else {
resolve(`${domain}: records: ${records}`);
}
});
});
}
// simulating getting domain names from a list
function* getDomains(num) {
let cnt = 0;
for (let ctr = 1; ctr < num+1; ctr++) {
// 97 = "a"; 123 = "z"
for (let charCode = 97; charCode < 123; charCode++) {
let prefix = '';
for (let p = 0; p < ctr; p++) {
prefix += `${String.fromCharCode(charCode)}`;
}
if (cnt === num) {
return null;
} else {
cnt += 1;
let domain = `${prefix}.com`;
yield domain;
}
}
}
}
function resolveDomain(num) {
let doms = getDomains(num);
function resolve(cnt, domain) {
if (cnt < 1) return;
if (cnt === num) return;
domainToIp_resolve(domain)
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
setImmediate(resolve.bind(null, cnt+1, doms.next().value));
}
resolve(1, doms.next().value);
}
resolveDomain(1000000);