承诺
我非常喜欢使用承诺并尽可能地将它们应用到各个方面。
这里有一个解决方案,我认为可以适用于您的情况。
var exec = require('child_process').exec;
var folders = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var maxConcurrentProcessCount = 5;
var promiseArr = [];
folders.forEach(function (folder) {
var pr = {
start: function () {
if (pr.promise) return pr.promise;
return pr.promise = new Promise(function (resolve) {
exec("tar cvf " + folder + ".tgz " + folder,
undefined, (err, stdout, stderr) => {
var ind = promiseArr.indexOf(pr);
if (ind >= 0) promiseArr.splice(ind, 1);
resolve(stdout);
});
});
}
};
promiseArr.push(pr);
});
var racePromises = function () {
if (!promiseArr.length) return;
Promise.race(promiseArr.slice(0, maxConcurrentProcessCount).map(x => x.start())).then(racePromises);
console.log("Current running process count: " + promiseArr.filter(x => x.promise).length);
}
racePromises();
简要说明
创建一个数组,其中每个元素代表一个任务。首先选择其中的5个并启动它们。每当其中一个完成时,将其从数组中删除,并再次从数组中启动5个任务。
示例运行
![测试示例](https://istack.dev59.com/pbfUa.webp)
只是为了好玩而使用 Promise 重新创建 eachLimit
var myEachLimit = function (collection, maxConcurrentCalls, callback) {
return new Promise(function (resolve, reject) {
var promiseArr = [];
collection.forEach(function (item) {
var pr = {
start: function () {
if (pr.promise) return pr.promise;
return pr.promise = new Promise(function (resolve) {
callback.call(item, item, function () {
var ind = promiseArr.indexOf(pr);
if (ind >= 0) promiseArr.splice(ind, 1);
resolve();
});
});
}
};
promiseArr.push(pr);
});
var racePromises = function () {
if (!promiseArr.length) {
resolve();
return;
}
Promise.race(promiseArr.slice(0, maxConcurrentProcessCount).map(x => x.start())).then(racePromises);
console.log("Current running process count: " + promiseArr.filter(x => x.promise).length);
}
racePromises();
});
}
var exec = require('child_process').exec;
var folders = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var maxConcurrentProcessCount = 5;
myEachLimit(folders, maxConcurrentProcessCount, function (folder, next) {
exec("tar cvf " + folder + ".tgz " + folder, (err, stdout, stderr) => {
next();
});
}).then(function () {
console.log("Finished all processes");
});