我的代码将大量文件从一个云存储转移到另一个云存储(同一区域)。工作流程正在下载源文件流,然后将流上载到目标存储。
如果在非承诺循环中运行它们,传输速度很快(比如100M / s),但会达到内存限制。最后服务器崩溃了。
如果在承诺链中,即在最后一个作业完成后运行下一个作业,崩溃问题就解决了,但转移速度非常慢(比如10M / s)。
我的问题:为什么承诺会影响下载&上传速度?或者我错过了什么?
代码段:
transferArray.forEach(function (eachTransfer) {
queue = queue.then(function(result){
// put result somewhere
return eachFileTransfer(jobId,userid,eachTransfer);
});
});
queue.then(function(){
console.log('done');
});
我正在考虑将PromisePool用于并发,但不确定速度会提高多少,以及我应该设置合理的并发数。裁判帖子: Execute promises concurrently with a buffer pool size in Javascript
答案 0 :(得分:0)
因为我猜你的循环你并行运行了很多请求,它会更快(但也会超过所有类型的限制)。因此,正如您所说,使用多个承诺链:
const inParallel = 10;
const promises = (new Array(inParallel)).fill(Promise.resolve());
for(const [index, transfer] of transferArray.entries())
promises[index % inParallel] = promises[index % inParallel].then(() => eachFileTransfer(jobId,userid,eachTransfer));
答案 1 :(得分:0)
最后,我通过PromisePool工作了。以下代码段基于另一篇帖子:Execute promises concurrently with a buffer pool size in Javascript
由于我的代码比这篇文章相对复杂,认为它可能对其他人有用:
var PromisePool = require('es6-promise-pool');
//single promises
function p1(){
return new Promise(function(resolve, reject) {
console.log('p1');
setTimeout(resolve, 2000, 'foo');
});
}
function p2(){
return new Promise(function(resolve, reject) {
console.log('p2');
setTimeout(resolve, 2000, 'foo');
});
}
function p3(){
return new Promise(function(resolve, reject) {
console.log('p3');
setTimeout(resolve, 2000, 'foo');
});
}
var tasks=[];
var loopIndex = 0;
[1,2,3,4,5,6,7,8].forEach(function(v,i){
console.log(v,i);
//build promise chain
var x = (v) => new Promise(function(resolve, reject) {
console.log(v);
p1().then(function(r){
return p2();
})
.then(function(r){
return p3();
})
.then(function(r){
//console.log('embedded chain done');
resolve('embedded chain done');
}).catch(function(e){
reject('embedded chain failed');
});
//setTimeout(resolve, 2000, 'foo');
})
//build one promise task
tasks.push({fun:x,param:i});
if(++loopIndex == 8){
//once the array is done
const promiseProducer = () => {
while(tasks.length) {
console.log('processing ');
const task = tasks.shift();
return task.fun(task.param);
}
return null;
}
// concurrent Promises set to 3
const pool = new PromisePool(promiseProducer, 3);
//start to promise all, yet with concurrent 3 tasks.
const poolPromise = pool.start();
poolPromise.then(() => { console.log('done!'); })
}
});