我正在编写一些代码来扫描目录,而我发现这可能不是最好的主意:
files.forEach(async fileName => {
stat = await lstat(fileName);
});
因为我要同时为目录中的每个文件触发一个lstat。有谁知道"清洁"这样做的方法?我正在考虑一个维护队列并将其排干的lib。
我知道一些" old"异步库执行此操作,但我不知道使用本机异步/等待调用执行此操作的任何内容
答案 0 :(得分:3)
一般来说,没有代码可以并行运行,因此几百个公开承诺不应该成为问题。
如果你想一个接一个地运行,而不是简单的for循环:
async function iterate(){
for(var i=0;i<files.length;i++){
stat = await lstat(files[i]);
}
}
要一次运行多个,但并非所有人都可以这样做:
async function iterate(){
var atonce=10;
for(var i=0;i<files.length;i+=atonce){
stats = await Promise.all(files.slice(i,i+atonce).map(file=>lstat(file));
}
}
另一种方式是一些Promise队列:
var current=0;
async function retrieve(){
if(current>=files.length) return;
current++;
await lstat(files[current-1]);
retrieve();
}
retrieve();//two in parallel
retrieve();
如果要并行运行,可以使用Promise.all来捕获结果(取决于用例):
Promise.all(files.map(async function(file){
return await lstat(file);
}).then(results=>...);
答案 1 :(得分:0)
你在找这样的东西吗?
//sry, but I didn't get up with a beter name
function Todo(numParalell = 8){
var todo = [], running = 0;
function init(resolve){
if(running < numParalell){
++running;
resolve();
}else{
todo.push(resolve);
}
}
function next(){
if(todo.length){
todo.shift()(); //FIFO
//todo.pop()(); //LIFO / FILO
}else{
--running;
}
}
return {
get numRunning(){ return running },
get numWaiting(){ return todo.length },
append(fn){
if(typeof fn !== "function"){
//fn ain't a function but a value
return Promise.resolve(fn);
}
var promise = new Promise(init).then(fn);
promise.then(next, next);
return promise;
}
}
}
//a queue that runs 4 tasks in paralell
var todo = Todo(4);
//some task that just kills some time
var someAsyncTask = v => new Promise(resolve => setTimeout(resolve, Math.random() * 5000, v));
//add 25 items to the todo-list
//and log the start and end time from now
var promises = Array(25).fill(Date.now())
.map((t,i) => todo.append(() => {
console.log('+starting', i, 'after', Date.now() - t, 'ms');
return someAsyncTask()
.then(() => console.log('-finished', i, 'after', Date.now() - t, 'ms'))
.then(() => 'resolve to ' + i);
}));
Promise.all(promises).then(arr => console.log("And the resolved promises:", arr));
.as-console-wrapper{top:0;max-height:100%!important}
Todo#append()
接受一个函数来执行您想要管理的异步任务,并返回带有结果的Promise。虽然该功能不会立即执行,但只要有空槽即可。
请注意,此代码无法解析依赖性,例如
var todo = Todo(1);
todo.append(() => todo.append(() => ...))
因此,您可能会遇到外部任务没有完成,因为它取决于/解析内部任务。内部人可能无法启动,因为此Todo列表中没有空闲插槽。