等待 x 数量的承诺完成以产生新承诺的好模式是什么?
What is a good pattern for waiting until x number of promises are completed to spawn a new promise?
我一直在搜索并找到了它的一些变体,但没有找到完全满足我需要的东西。下面是我试图找出的伪代码:
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
是我可以用来执行此操作的东西,但我不太理解必要的逻辑。任何和所有帮助将不胜感激,如果有任何其他我可以编辑它以帮助别人更好地理解问题,请告诉我,谢谢!
由于 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
修饰返回 Promise 的函数。
let flag = true;
while (flag) {
if (pending.size <= maxPendingItems) {
// promise will automatically queue until resolved
performAsyncIO().then(responseHandler);
}
}
我想您可能会发现 Bluebird 库中的 Promise.map
之类的东西很有用。 concurrency
参数允许您设置 "pending" 承诺的最大数量。
简单的解决方案,但我想不像 Bluebird 那样经得起考验,可作为 standalone NPM package。
我一直在搜索并找到了它的一些变体,但没有找到完全满足我需要的东西。下面是我试图找出的伪代码:
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
是我可以用来执行此操作的东西,但我不太理解必要的逻辑。任何和所有帮助将不胜感激,如果有任何其他我可以编辑它以帮助别人更好地理解问题,请告诉我,谢谢!
由于 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
修饰返回 Promise 的函数。
let flag = true;
while (flag) {
if (pending.size <= maxPendingItems) {
// promise will automatically queue until resolved
performAsyncIO().then(responseHandler);
}
}
我想您可能会发现 Bluebird 库中的 Promise.map
之类的东西很有用。 concurrency
参数允许您设置 "pending" 承诺的最大数量。
简单的解决方案,但我想不像 Bluebird 那样经得起考验,可作为 standalone NPM package。