承诺链中的缓慢

时间:2018-04-10 16:56:40

标签: javascript promise es6-promise

我的代码将大量文件从一个云存储转移到另一个云存储(同一区域)。工作流程正在下载源文件流,然后将流上载到目标存储。

如果在非承诺循环中运行它们,传输速度很快(比如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

2 个答案:

答案 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!'); })
    }  

});