Node.js-希望对循环中的方法进行5次并行调用
我在MongoDB集合中有1000个信息文件。我正在编写一个查询以获取1000条记录,在一个循环中,我正在调用一个函数将该文件下载到本地系统。因此,下载所有1000个文件是一个循序渐进的过程 我希望在下载过程中有一些并行性。在循环中,我想一次下载10个文件,这意味着我想调用下载函数10次,完成10个文件下载后,我想下载下10个文件(这意味着我需要调用下载函数10次) 我如何实现这种并行性,或者有更好的方法来实现这一点 我看到了Node.js-希望对循环中的方法进行5次并行调用,node.js,express,async.js,kue,Node.js,Express,Async.js,Kue,我在MongoDB集合中有1000个信息文件。我正在编写一个查询以获取1000条记录,在一个循环中,我正在调用一个函数将该文件下载到本地系统。因此,下载所有1000个文件是一个循序渐进的过程 我希望在下载过程中有一些并行性。在循环中,我想一次下载10个文件,这意味着我想调用下载函数10次,完成10个文件下载后,我想下载下10个文件(这意味着我需要调用下载函数10次) 我如何实现这种并行性,或者有更好的方法来实现这一点 我看到了Kuenpm,但是如何实现这一点呢?顺便说一句,我是从FTP下载的,所
Kue
npm,但是如何实现这一点呢?顺便说一句,我是从FTP下载的,所以我使用基本FTP
npm进行FTP操作。该库在这方面功能非常强大,一旦您了解了基本知识,也非常容易
我建议你使用它,这样你的应用程序就不必担心一批十个文件的循环,它只会让十个文件同时下载
var files = ['a.txt', 'b.txt']
var concurrency = 10;
async.eachLimit(files, concurrency, downloadFile, onFinish);
function downloadFile(file, callback){
// run your download code here
// when file has downloaded, call callback(null)
// if there is an error, call callback('error code')
}
function onFinish(err, results){
if(err) {
// do something with the error
}
// reaching this point means the files have all downloaded
}
异步库将并行运行downloadFile
,从files
列表中向每个实例发送一个条目,然后当列表中的每个项目都完成时,它将调用onFinish库在这方面非常强大,并且一旦您了解了基本知识,该库也非常简单
我建议你使用它,这样你的应用程序就不必担心一批十个文件的循环,它只会让十个文件同时下载
var files = ['a.txt', 'b.txt']
var concurrency = 10;
async.eachLimit(files, concurrency, downloadFile, onFinish);
function downloadFile(file, callback){
// run your download code here
// when file has downloaded, call callback(null)
// if there is an error, call callback('error code')
}
function onFinish(err, results){
if(err) {
// do something with the error
}
// reaching this point means the files have all downloaded
}
异步库将并行运行downloadFile
,从files
列表中向每个实例发送一个条目,然后当列表中的每个项目都完成时,它将调用onFinish
,而不查看您的实现,我只能提供一个通用答案
假设您的下载函数接收到一个fileId,并返回一个承诺,该承诺在所述文件完成下载时解析。对于这个POC,我将模拟它,并承诺在200到500毫秒后解析为文件名
function download(fileindex) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(`file_${fileindex}`);
},200+300*Math.random());
});
}
您有1000个文件,并希望在100次迭代中下载它们,每次迭代10个文件
让我们把东西封装起来。我将声明一个函数,该函数接收起始ID和大小,并返回[N…N+size]
ID
function* range(bucket, size=10) {
let start = bucket*size,
end=start+size;
for (let i = start; i < end; i++) {
yield i;
}
}
A在这一点上,bucket
的内容是:
[
[file0 ... file9]
...
[file 990 ... file 999]
]
然后,使用for..of
(支持异步)迭代存储桶
在每次迭代中,使用Promise.all
将10个调用排入download
async function proceed() {
for await(let bucket of buckets) { // for...of
await Promise.all(bucket.reduce((accum,fileindex)=>{
accum.push(download(fileindex));
return accum;
},[]));
}
}
让我们看一个正在运行的示例(只有10个bucket,我们在这里都很忙:D)
函数下载(文件索引){
返回新承诺((解决、拒绝)=>{
let file=`file_${fileindex}`;
设置超时(()=>{
解决(文件);
},200+300*Math.random());
});
}
功能*范围(铲斗,尺寸=10){
让我们开始=桶*大小,
结束=开始+大小;
for(让i=start;i{
返回[…范围(桶,10)];
});
异步函数继续(){
假设bucketNumber=0,
timeStart=performance.now();
等待(让桶中的桶){
让startingTime=Number((performance.now()-timeStart)/1000).toFixed(1).substr(-5),
结果=等待承诺.all(bucket.reduce)(累计、文件索引)=>{
累计推送(下载(文件索引));
返回累计;
}, []));
console.log(
`${startingTime}的下载桶${bucketNumber}`
);
等待结果;
让endingTime=Number((performance.now()-timeStart)/1000).toFixed(1.substr(-5);
console.log(
`${endingTime}的存储桶${bucketNumber++}完成:`,
`[${result[0]}…${result.pop()}]`
);
}
}
document.querySelector(“#继续”).addEventListener('click',继续)代码>
继续
在没有看到您的实现的情况下,我只能提供一个通用的答案
假设您的下载函数接收到一个fileId,并返回一个承诺,该承诺在所述文件完成下载时解析。对于这个POC,我将模拟它,并承诺在200到500毫秒后解析为文件名
function download(fileindex) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(`file_${fileindex}`);
},200+300*Math.random());
});
}
您有1000个文件,并希望在100次迭代中下载它们,每次迭代10个文件
让我们把东西封装起来。我将声明一个函数,该函数接收起始ID和大小,并返回[N…N+size]
ID
function* range(bucket, size=10) {
let start = bucket*size,
end=start+size;
for (let i = start; i < end; i++) {
yield i;
}
}
A在这一点上,bucket
的内容是:
[
[file0 ... file9]
...
[file 990 ... file 999]
]
然后,使用for..of
(支持异步)迭代存储桶
在每次迭代中,使用Promise.all
将10个调用排入download
async function proceed() {
for await(let bucket of buckets) { // for...of
await Promise.all(bucket.reduce((accum,fileindex)=>{
accum.push(download(fileindex));
return accum;
},[]));
}
}
让我们看一个正在运行的示例(只有10个bucket,我们在这里都很忙:D)
函数下载(文件索引){
返回新承诺((解决、拒绝)=>{
let file=`file_${fileindex}`;
设置超时(()=>{
解决(文件);
},200+300*Math.random());
});
}
功能*范围(铲斗,尺寸=10){
让我们开始=桶*大小,
结束=开始+大小;
for(让i=start;i{
返回[…范围(桶,10)];
});
异步函数继续(){
假设bucketNumber=0,
timeStart=performance.now();
等待(让桶中的桶){
让startingTime=Number((performance.now()-timeStart)/1000).toFixed(1).substr(-5),
结果=等待承诺.all(bucket.reduce)(累计、文件索引)=>{
累计推送(下载(文件索引));
返回累计;
}, []));
console.log(
`${startingTime}的下载桶${bucketNumber}`
);
等待结果;
让endingTime=Number((performance.now()-timeStart)/1000).toFixed(1.substr(-5);
console.log(
`${endingTime}的存储桶${bucketNumber++}完成:`,
`[${result[0]}…${result.pop()}]`
);
}
}
document.querySelector(“#继续”).addEventListener('click',继续)代码>