2016-11-22 29 views
0

我一直在寻找,并找到了一些变化,但没有找到任何符合我的需求。下面是我想弄清楚的伪代码:我不明白,你不能阻止同步码等待异步和我尝试了好几种变化等待x个承诺完成以产生新承诺的良好模式是什么?

var itemsUploading = 0; 
const maxUploads = 10; 


function uploadAll(items){ 
    var promises = []; 
    items.forEach(function(item){ 

     /* Here is where I want to wait for itemsCurrentlyUploading < maxUploads */ 

     itemsUploading++;    
     promises.push(upload(item));    
    } 
    return Promise.all(promises); 

} 

function upload(item){ 
    return new Promise(function(resolve, reject){ 

     /*Item upload logic here */ 

    }) 
    .then(function(response){ 
     itemsUploading--; 
    }); 
} 

。我认为setTimeout是我可以用来做到这一点的东西,但我不太明白必要的逻辑。任何和所有的帮助将不胜感激,如果还有其他事情可以编辑,以帮助某人更好地理解问题,请让我知道,谢谢!

+0

你需要阅读关于链接Promise和Deferred调用,这里的关键字是'.then()' – rorschach

+2

看看[this](http://stackoverflow.com/a/39197252/1048572)或[this ](http://stackoverflow.com/a/38778887/1048572) – Bergi

回答

1

我想你可能会发现像Bluebird库中的Promise.map有用。 concurrency参数允许您设置“等待”承诺的最大数量。

简单的解决方案,但我想不像蓝鸟那样经过战斗测试,可以用作standalone NPM package

+0

这是完美的,正是我所期待的。 – goodOldFashioned

0

由于JavaScript在数据结构上有点稀疏,所以我们必须做。

let pending = new Set; 
let maxPendingItems = 5; // could be whatever number 

let wrapPromiseFn = f => (...args) => { 
    let p = f(...args); 
    pending.add(p); 
    p 
    .then(() => pending.remove(p)) 
    .catch(e => { 
     console.warn(e); 
     pending.remove(p); 
    }); 

    return p; 
}; 

let performAsyncIO = wrapPromiseFn(someAJAXFn); 

现在你可以有一个循环,监视集的大小,看它是否已经清理出足够的添加新的项目。只要确保你像上面那样用wrapPromiseFn来装饰你的承诺返回函数。

let flag = true; 
while (flag) { 
    if (pending.size <= maxPendingItems) { 
    // promise will automatically queue until resolved 
    performAsyncIO().then(responseHandler); 
    } 
}