在 Node.JS 中应该避免循环还是有特殊的方法来处理它们?
Posted
技术标签:
【中文标题】在 Node.JS 中应该避免循环还是有特殊的方法来处理它们?【英文标题】:Should loops be avoided in Node.JS or is there a special way to handle them? 【发布时间】:2017-06-13 06:45:54 【问题描述】:循环阻塞。他们似乎对 Node.JS 的想法漠不关心。如何处理for
循环或while
循环似乎是最佳选择的流程。
例如,如果我想打印一个直到number * 1000
的随机数表,我会想使用for
循环。在 Node.JS 中是否有一种特殊的方法来处理这个问题?
【问题讨论】:
(不是反对者)但循环在大多数情况下在 Node 中并不令人讨厌。这取决于用例,但有时异步选项更适合,有时同步操作更适合特定场景 【参考方案1】:循环本身并不坏,但这取决于具体情况。在大多数情况下,您需要在循环中执行一些异步操作。
所以我个人的偏好是根本不使用循环,而是使用功能对应物(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));
请注意,您可以轻松地在同步和异步版本之间进行更改,结构几乎保持不变。
希望这会有所帮助。
【讨论】:
【参考方案2】:如果你对内存中的数据进行循环(例如,你想遍历一个数组并向所有对象添加一个道具),循环将正常工作,但如果你需要在循环内做一些事情,比如保存值到数据库,你会遇到一些问题。
我意识到这不是完全正确的答案,但它是一个可能对某人有所帮助的建议。我发现处理这个问题的最简单方法之一是使用带有 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();
);
);
);
;
【讨论】:
以上是关于在 Node.JS 中应该避免循环还是有特殊的方法来处理它们?的主要内容,如果未能解决你的问题,请参考以下文章
是否应该为互斥锁获取-交换循环(或队列获取-加载循环)组合内存栅栏,还是应该避免?
Node.js 中 For 循环中的 async.waterfall