Ответ 1
Вместо setTimeout лучше использовать process.nextTick или setImmediate (в зависимости от того, когда вы хотите, чтобы ваш обратный вызов выполнялся). Но недостаточно добавить длинный код в функцию, потому что он по-прежнему будет блокировать поток, только через миллисекунду позже.
Вам нужно разбить свой код и запустить setImmediate или process.nextTick несколько раз - как на каждой итерации, а затем назначить новую итерацию. В противном случае вы ничего не выиграете.
Пример
Вместо этого кода:
var a = 0, b = 10000000;
function numbers() {
while (a < b) {
console.log("Number " + a++);
}
}
numbers();
вы можете использовать такой код:
var a = 0, b = 10000000;
function numbers() {
var i = 0;
while (a < b && i++ < 100) {
console.log("Number " + a++);
}
if (a < b) setImmediate(numbers);
}
numbers();
Первый заблокирует ваш поток (и, вероятно, переполнит ваш стек вызовов), а второй не будет блокироваться (или, точнее, он будет блокировать поток 10000000 раз в течение очень короткого момента, позволяя другим вещам запускаться в между этими моментами).
Вы также можете рассмотреть возможность нереста внешнего процесса или записи собственного добавления в C/С++, где вы можете использовать потоки.
Подробнее см.: