Javascript 如何接受通过过滤器的前N个承诺?
如果我有一个值数组,并且我使用这些值执行一个执行承诺的检查,那么如何获取通过检查的前N个承诺 对于下面的示例,我只需要返回承诺的前三个奇数,由函数Javascript 如何接受通过过滤器的前N个承诺?,javascript,promise,Javascript,Promise,如果我有一个值数组,并且我使用这些值执行一个执行承诺的检查,那么如何获取通过检查的前N个承诺 对于下面的示例,我只需要返回承诺的前三个奇数,由函数isOdd确定 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)
isOdd
确定
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);
const collection=[1,2,3,4,5,6,7,8,9,10];
const len=collection.length;
常量结果=[];
设指数=-1;
函数isOdd(值){
如果(值%2!==0){
返还承诺。决议(1);
}否则{
返回承诺。解决(0);
}
}
而(++指数==3){
打破
}
}
承诺。全部(结果)。然后(doMoreStuff);
我重复了一下这个问题,假设您提到的“过滤器”实际上是一个承诺正在履行与被拒绝,而不是履行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个承诺是否已解决,在这种情况下,解决整个承诺
然后:
这不处理少于n个承诺实现的情况,也不处理边缘情况,例如n大于承诺数量。这只是一个练习
原始问题
如果您想坚持使用值为0或1的承诺定义,请安排将谓词(此处称为filter
)传递给takefirstn,其函数如下所示:
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));
承诺不会被阻止,所以当其他人完成承诺时,没有真正的方法停止履行承诺。我能想到的最接近的就是这样
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(', ');
);
});
const collection=[1,2,3,4,5,6,7,8,9,10];
const len=collection.length;
常量结果=[];
设指数=-1;
函数isOdd(值){
如果(值%2!==0){
返还承诺。决议(1);
}否则{
返回承诺。解决(0);
}
}
而(++指数
但正如你所见,它抓住了所有的奇数值。您可以将if(results.length<3)…
移动到resolve函数,但这不会阻止它在每个元素上运行它返回的数量。但这不起作用。承诺。在将任何内容推送到结果
之前,将调用所有
。感谢您的全面响应。我学到了很多关于何时/如何在Promise构造函数中使用executor的知识。我要接受。不过,我还有一个后续问题:在您的实现中,您有collection.map
,如果我想节省时间,不在整个集合上运行映射函数,而是迭代,一旦我有3个承诺解决了1,就停下来吧?在你创建并运行它们之前,你不知道哪些承诺会解决。再次感谢@torazaburo,你帮了我很大的忙。+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(', ');
);
});