Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何接受通过过滤器的前N个承诺?_Javascript_Promise - Fatal编程技术网

Javascript 如何接受通过过滤器的前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)

如果我有一个值数组,并且我使用这些值执行一个执行承诺的检查,那么如何获取通过检查的前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) {
        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(', ');
  ); 
});