如果我有一个值数组,并且我使用这些值来执行执行承诺的检查,那么如何获取通过检查的前N个Promise?
对于下面的例子,我只想要前面三个奇数,由函数isOdd
确定,它返回一个promise。
const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const len = collection.length;
const results = [];
let index = -1;
function isOdd(value) {
if (value % 2 !== 0) {
return Promise.resolve(1);
} else {
return Promise.resolve(0);
}
}
while (++index < len) {
const currentValue = collection[index];
const result = isOdd(currentValue);
// append the result to an array of results IF Promise.resolve's value === 1
if (results.length >== 3) {
break;
}
}
Promise.all(results).then(doMoreStuff);
答案 0 :(得分:3)
我正在重述这个问题,假设你提到的“过滤器”实际上是一个承诺被完成而被拒绝,而不是满足于0对1.换句话说:
function isOdd(value) {
if (value % 2 !== 0) {
return Promise.resolve();
} else {
return Promise.reject();
}
}
你只需要编写逻辑。
function takeFirstN(promises, n) {
const results = [];
if (!promises.length) return Promise.resolve([]);
return new Promise(resolve => {
for (promise of promises) {
promise.then(result => {
results.push(result);
if (!(--n)) resolve(results);
});
}
});
}
换句话说,开始所有的承诺。当每个人结算时,将其结果放在结果列表中,并检查 n 承诺是否已解决,在这种情况下解决整体承诺。
然后:
const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
takefirstN(collection.map(isOdd), 3)
.then(results => console.log(results));
这不涉及小于 n 承诺的情况,或处理 n 等边缘情况大于承诺数的情况。这是一个练习。
如果你想坚持使用值为0或1的promises定义,那么安排将谓词(在这里称为filter
)传递给takeFirstNWhich
函数,如下所示:
function takeFirstNWhich(promises, filter, n) {
const results = [];
if (!promises.length) return Promise.resolve([]);
return new Promise(resolve => {
for (promise of promises) {
promise.then(result => {
if (filter(result)) {
results.push(result);
if (!(--n)) resolve(results);
}
});
}
});
}
现在你可以写:
takefirstNWhich(collection.map(isOdd), odd => odd, 3)
.then(results => console.log(results));
答案 1 :(得分:-1)
承诺没有阻止,因此当其他人完成时,没有真正的方法可以停止运行它们。我能想到的最接近的就是这样。
const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const len = collection.length;
const results = [];
let index = -1;
function isOdd(value) {
if (value % 2 !== 0) {
return Promise.resolve(1);
} else {
return Promise.resolve(0);
}
}
while (++index < len) {
const currentValue = collection[index];
if(results.length < 3) {
isOdd(currentValue).then(
function(result) {
if(result == 1) {
results.push(currentValue);
}
}
);
}
}
Promise.all(results).then(
function() {
alert("done: " + results.join(', ');
);
});
但正如你所看到的那样,抓住了所有奇数值。您可以将if(results.length < 3)...
移动到解析函数,但不会阻止它在每个元素上运行它返回的数量。