2017-01-27 2 views
1

Петли блокируются. Они кажутся безразличными к идее Node.JS. Как обрабатывать поток, где наилучшим вариантом является цикл for или цикл while.Следует ли избегать циклов в Node.JS или есть специальный способ их обработки?

Например, если я хочу напечатать таблицу случайного числа до number * 1000, я бы хотел использовать цикл for. Есть ли специальный способ справиться с этим в Node.JS?

+3

(не downvoter), но петли не одобряется в узле по большей части , Это зависит от варианта использования, но иногда асинхронные параметры лучше подходят, а иногда синхронные операции лучше подходят для конкретного сценария –

ответ

3

Петли само по себе плохо, но это зависит от ситуации. В большинстве случаев вам нужно будет сделать некоторые асинхронные вещи внутри циклов.

Таким образом, мое личное предпочтение заключается в том, чтобы не использовать циклы вообще, а вместо этого использовать функциональные аналоги (forEach/map/reduce/filter). Таким образом, моя база кода остается последовательной (и цикл синхронизации легко заменяется на асинхронный, если это необходимо).

const myArr = [1, 2, 3]; 
// sync loops 
myArr.forEach(syncLogFunction); 
console.log('after sync loop'); 

function syncLogFunction(entry) { 
    console.log('sync loop', entry); 
} 

// now we want to change that into an async operation: 
Promise.all(myArr.map(asyncLogFunction)) 
.then(() => console.log('after async loop')); 

function asyncLogFunction(entry) { 
    console.log('async loop', entry); 
    return new Promise(resolve => setTimeout(resolve, 100)); 
} 

Обратите внимание, как легко вы можете переключаться между версиями синхронизации и асинхронности, структура остается практически такой же.

Надеюсь, это поможет.

-1

Если вы делаете петли на данных в памяти (например, вы хотите пройти через массив и добавить опору для всех объектов), петли будут работать нормально, но если вам нужно что-то сделать в цикле, как save значения в БД, вы столкнетесь с некоторыми проблемами.

Я понимаю, что это не совсем ответ, но это предложение, которое может помочь кому-то. Я нашел один из самых простых способов решения этой проблемы - использовать ограничитель скорости с forEach (мне не очень нравятся обещания). Это также дает дополнительное преимущество иметь возможность обрабатывать вещи параллельно, но только двигаться дальше, когда все сделано: https://github.com/jhurliman/node-rate-limiter

var RateLimiter = require('limiter').RateLimiter; 
var limiter = new RateLimiter(1, 5); 

exports.saveFile = function (myArray, next) { 
    var completed = 0; 
    var totalFiles = myArray.length; 

    myArray.forEach(function (item) { 
     limiter.removeTokens(1, function() { 
      //call some async function 
      saveAndLog(item, function (err, result) { 
       //check for errors 

       completed++; 

       if (completed == totalFiles) { 
        //call next function 
        exports.process(); 
       } 
      }); 
     }); 
    }); 
};