【问题标题】:async.js: iterate a collection until one returns trueasync.js:迭代一个集合,直到一个返回 true
【发布时间】:2018-02-09 19:59:25
【问题描述】:

我对 async.js 的功能非常满意,但它似乎缺少我现在需要它做的一件事:

我有一个包含数据的数组。

[{"name": "bob", "age":15},
 {"name": "bill", "age":19},
 {"name": "john", "age": 24}]

我想以 array[i] 作为参数调用 same 函数,直到它为数组的内容之一返回 true。 (在此示例中,可能将用户写入数据库,直到其中一个至少具有指定年龄,否则返回错误)。 所以: 尝试鲍勃->错误 然后尝试账单 -> 成功 -> 然后继续下一个任务,不要继续

我发现的所有东西都需要一组函数(不是数据),或者似乎不知道“尝试直到找到匹配的”的想法。

或者也许我没有充分阅读docs? 我怎样才能做到这一点?谢谢

【问题讨论】:

  • 你为什么还要使用async呢?迭代一个数组直到某个条件为真只需要基本的循环逻辑,热确定异步如何或为什么进入图片。您可以发布到目前为止您尝试过的完整代码吗?还是minimal reproducible example
  • 因为我想在每次迭代时调用服务器。我注意到一个正常的 for 循环只是继续,而不是等待第一个成功。所以我认为 async 可能能够将调用排队并在成功时继续使用另一个函数
  • caolan.github.io/async/docs.html#some 如果 coll 中的至少一个元素满足异步测试,则返回 true。如果任何 iteratee 调用返回 true,则立即调用主回调。
  • 我会调查一下,谢谢!
  • 虽然在从服务器获取内容的同时使用它听起来是个坏主意,因为它可能会在并行中这样做,并且您仍然会有多个请求,因为它们排队的速度比完成的速度要快。最好有一个数据端点,只需在结果集上执行一个普通的some 谓词。也许下一个限制为 1 的 someLimit 会起作用,但仍然不理想

标签: javascript arrays async.js


【解决方案1】:

使用纯 js 很容易。只需将递归迭代包装在 Promise 中即可:

var some = new Promise( res => {
  const arr = [{"name": "bob", "age":15}, {"name": "bill", "age":19},{"name": "john", "age": 24}];
  (function next(i){
    if(i>=arr.length) return res(false);
    someasync(arr[i]).then(result => {
      if(result){
        res(true);
      }else{
        next(i+1);
      }
    });
  })(0);
});

ESnext 中也是一样的:

async function some( func, params ){
 for(var i = 0; i < params.length; i++){
   if( await func(params[i]) ){
     return true;
   }
 }
 return false;
}

some(a=>a%2==0, [0,1,2,3,4]).then(alert);

【讨论】:

  • mhhh 抱歉,这不是我所说的“很容易”。虽然它可能有效,但我想避免很多开销
  • @devman 如果这是开销,为什么要嵌入整个库:/ ??
  • 开销与“字符开销”相同。我宁愿有库写2行,也不愿没有库写10行
  • @devman 您可以编写简短、漂亮或快速的代码。你不能拥有这一切。上面的代码可能不短,但我认为它的可读性和速度相当快。
猜你喜欢
  • 2021-05-07
  • 1970-01-01
  • 2017-05-02
  • 2010-09-23
  • 1970-01-01
  • 2021-02-20
  • 2013-05-08
  • 1970-01-01
相关资源
最近更新 更多