异步流程控制 遍历篇filter

文章目录

  • 基础方法
    • arrayEachIndexValue
    • baseEachIndexValue
    • symbolEachIndexValue
    • compact
    • timesSync
  • 异步遍历
    • filter
    • filterLimit
    • filterSeries

基础方法

arrayEachIndexValue

function arrayEachIndexValue(array, iterator, createCallback) {
  var value;
  var index = -1;
  var size = array.length;

  if (iterator.length === 3) {
    while (++index < size) {
      value = array[index];
      iterator(value, index, createCallback(index, value));
    }
  } else {
    while (++index < size) {
      value = array[index];
      iterator(value, createCallback(index, value));
    }
  }
}

baseEachIndexValue

function baseEachIndexValue(object, iterator, createCallback, keys) {
  var key, value;
  var index = -1;
  var size = keys.length;

  if (iterator.length === 3) {
    while (++index < size) {
      key = keys[index];
      value = object[key];
      iterator(value, key, createCallback(index, value));
    }
  } else {
    while (++index < size) {
      value = object[keys[index]];
      iterator(value, createCallback(index, value));
    }
  }
}

symbolEachIndexValue

function symbolEachIndexValue(collection, iterator, createCallback) {
  var value, item;
  var index = 0;
  var iter = collection[iteratorSymbol]();

  if (iterator.length === 3) {
    while ((item = iter.next()).done === false) {
      value = item.value;
      iterator(value, index, createCallback(index++, value));
    }
  } else {
    while ((item = iter.next()).done === false) {
      value = item.value;
      iterator(value, createCallback(index++, value));
    }
  }
  return index;
}

compact

  • 筛选数组中所有true的元素
function compact(array) {
  var index = -1;
  var size = array.length;
  var result = [];

  while (++index < size) {
    var value = array[index];
    if (value) {
      result[result.length] = value;
    }
  }
  return result;
}

timesSync

function timesSync(n, iterator) {
  var index = -1;
  while (++index < n) {
    iterator(index);
  }
}

异步遍历

filter

基本使用

// array
var order = [];
var array = [1, 3, 2];
var iterator = function(num, done) {
  setTimeout(function() {
    order.push(num);
    done(null, num % 2);
  }, num * 10);
};
async.filter(array, iterator, function(err, res) {
  console.log(res); // [1, 3];
  console.log(order); // [1, 2, 3]
});

实现

var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true);

function createFilter(arrayEach, baseEach, symbolEach, bool) {
  return function(collection, iterator, callback) {
    callback = callback || noop;
    var size, keys, result;
    var completed = 0;

    if (isArray(collection)) {
      size = collection.length;
      result = Array(size);
      arrayEach(collection, iterator, createCallback);
    } else if (!collection) {
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
      result = [];
      size = symbolEach(collection, iterator, createCallback);
      size && size === completed && callback(null, compact(result));
    } else if (typeof collection === obj) {
      keys = nativeKeys(collection);
      size = keys.length;
      result = Array(size);
      baseEach(collection, iterator, createCallback, keys);
    }
    if (!size) {
      return callback(null, []);
    }

    function createCallback(index, value) { // 闭包记录索引和元素值
      return function done(err, res) {
        if (index === null) {
          throwError();
        }
        if (err) {
          index = null;
          callback = once(callback);
          callback(err);
          return;
        }
        if (!!res === bool) { // 异步回调结果为true时才记录
          result[index] = value; // 通过闭包index保存异步任务对应位置
        }
        index = null;
        if (++completed === size) { // 会等到所有任务执行完毕后,筛选出true的元素
          callback(null, compact(result));
        }
      };
    }
  };
}

filterLimit

  • 限制每次执行的异步任务数量
var filterLimit = createFilterLimit(true);

function createFilterLimit(bool) {
  return function(collection, limit, iterator, callback) {
    callback = callback || noop;
    var size, index, key, value, keys, iter, item, iterate, result;
    var sync = false;
    var started = 0;
    var completed = 0;

    if (isArray(collection)) {
      size = collection.length;
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
    } else if (!collection) {
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
      size = Infinity;  // 注意迭代器类型不知道size有多少个
      result = [];
      iter = collection[iteratorSymbol]();
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
    } else if (typeof collection === obj) {
      keys = nativeKeys(collection);
      size = keys.length;
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
    }
    if (!size || isNaN(limit) || limit < 1) {
      return callback(null, []);
    }
    result = result || Array(size);
    timesSync(limit > size ? size : limit, iterate);

    function arrayIterator() {
      index = started++;
      if (index < size) {
        value = collection[index];
        iterator(value, createCallback(value, index));
      }
    }

    function arrayIteratorWithIndex() {
      index = started++;
      if (index < size) {
        value = collection[index];
        iterator(value, index, createCallback(value, index));
      }
    }

    function symbolIterator() {
      item = iter.next();
      if (item.done === false) {
        value = item.value;
        iterator(value, createCallback(value, started++));
      } else if (completed === started && iterator !== noop) { // completed === started 表明已迭代完毕,createCallback对于迭代器类型只负责++completed
        iterator = noop;
        callback(null, compact(result));
      }
    }

    function symbolIteratorWithKey() {
      item = iter.next();
      if (item.done === false) {
        value = item.value;
        iterator(value, started, createCallback(value, started++));
      } else if (completed === started && iterator !== noop) {
        iterator = noop;
        callback(null, compact(result));
      }
    }

    function objectIterator() {
      index = started++;
      if (index < size) {
        value = collection[keys[index]];
        iterator(value, createCallback(value, index));
      }
    }

    function objectIteratorWithKey() {
      index = started++;
      if (index < size) {
        key = keys[index];
        value = collection[key];
        iterator(value, key, createCallback(value, index));
      }
    }

    function createCallback(value, index) {
      return function(err, res) {
        if (index === null) {
          throwError();
        }
        if (err) {
          index = null;
          iterate = noop;
          callback = once(callback);
          callback(err);
          return;
        }
        if (!!res === bool) {
          result[index] = value;
        }
        index = null;
        if (++completed === size) {
          callback = onlyOnce(callback);
          callback(null, compact(result));
        } else if (sync) {
          nextTick(iterate);
        } else {
          sync = true;
          iterate();
        }
        sync = false;
      };
    }
  };
}

filterSeries

  • 串行执行,在上一个任务done之后再执行下一个任务
var filterSeries = createFilterSeries(true);

function createFilterSeries(bool) {
  return function(collection, iterator, callback) {
    callback = onlyOnce(callback || noop);
    var size, key, value, keys, iter, item, iterate;
    var sync = false;
    var completed = 0;
    var result = [];

    if (isArray(collection)) {
      size = collection.length;
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
    } else if (!collection) {
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
      size = Infinity;
      iter = collection[iteratorSymbol]();
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
    } else if (typeof collection === obj) {
      keys = nativeKeys(collection);
      size = keys.length;
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
    }
    if (!size) {
      return callback(null, []);
    }
    iterate();

    function arrayIterator() {
      value = collection[completed];
      iterator(value, done);
    }

    function arrayIteratorWithIndex() {
      value = collection[completed];
      iterator(value, completed, done);
    }

    function symbolIterator() {
      item = iter.next();
      value = item.value;
      item.done ? callback(null, result) : iterator(value, done);
    }

    function symbolIteratorWithKey() {
      item = iter.next();
      value = item.value;
      item.done ? callback(null, result) : iterator(value, completed, done);
    }

    function objectIterator() {
      key = keys[completed];
      value = collection[key];
      iterator(value, done);
    }

    function objectIteratorWithKey() {
      key = keys[completed];
      value = collection[key];
      iterator(value, key, done);
    }

    function done(err, res) {
      if (err) {
        callback(err);
        return;
      }
      if (!!res === bool) {
        result[result.length] = value;
      }
      if (++completed === size) {
        iterate = throwError;
        callback(null, result);
      } else if (sync) {
        nextTick(iterate);
      } else {
        sync = true;
        iterate();
      }
      sync = false;
    }
  };
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/5023.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mars3d项目启动上的一些坑

前言 最近新入职了一家公司&#xff0c;公司新开了有个未来城市的项目&#xff0c;需要用到3D城市建模&#xff0c;公司老总选了Mars3d作为前端框架&#xff0c;项目分给我了&#xff0c;又是一个全新的领域&#xff0c;开搞吧&#xff01; 下面是自己遇到的几个小问题&#x…

day2 操作系统考点

一、重点知识点 进程管理&#xff1a;进程三态图、前趋图、同步与互斥、PV操作、死锁、线程。存储管理&#xff1a;分页存储管理、分段存储管理设备管理&#xff1a;I/O软件层次、SPOOLING技术文件管理&#xff1a;索引文件结构、文件目录、位示图计算 二、进程管理 1、进程三…

程序猿成长之路之密码学篇-AES算法介绍

DES算法介绍总算告一段落了&#xff0c;DES由于它的密钥每组只有64位&#xff0c;安全性能堪忧&#xff0c;为此阿美丽卡&#xff08;美国&#xff09;相继推出了3DES、AES等对称加密算法。3DES为此不在赘述&#xff0c;有兴趣的小伙伴可以网上找找“攻略”。接下来介绍一下AES…

JAVA电子招标采购系统源码—企业战略布局下的采购

​ 智慧寻源 多策略、多场景寻源&#xff0c;多种看板让寻源过程全程可监控&#xff0c;根据不同采购场景&#xff0c;采取不同寻源策略&#xff0c; 实现采购寻源线上化管控&#xff1b;同时支持公域和私域寻源。 询价比价 全程线上询比价&#xff0c;信息公开透明&#xff0…

Maven项目混淆、瘦身、打包exe

项目混淆 ProGuard 是一个混淆代码的开源项目&#xff0c;它的主要作用是混淆代码&#xff0c;ProGuard 包括以下 4 个功能&#xff1a; 压缩(Shrink)&#xff1a;检测并移除代码中无用的类、字段、方法和特性&#xff08;Attribute&#xff09; 优化(Optimize)&#xff1a;对…

Redis缓存击穿和穿透以及雪崩

缓存穿透 缓存穿透问题解决方案 缓存空对象布隆过滤器redisson 实现布隆过滤器 引入依赖预先放入数据使用 缓存击穿缓存雪崩 预防和解决方案 热点key的重建优化 缓存穿透 缓存穿透指的是查询一个根本不存在的数据&#xff0c;缓存层和存储层都不会命中&#xff0c;通常处于…

Shell echo 命令

文章目录Shell echo命令1.显示普通字符串:2.显示转义字符3.显示变量4.显示换行5.显示不换行6.显示结果定向至文件7.原样输出字符串&#xff0c;不进行转义或取变量(用单引号)8.显示命令执行结果Shell echo命令 Shell 的 echo 指令与 PHP 的 echo 指令类似&#xff0c;都是用于字…

@PostConstruct注解

PostConstruct注解 定义&#xff1a; PostConstruct是Java自带的注解&#xff0c;在方法上加该注解会在项目启动的时候执行该方法&#xff0c;也可以理解为在spring容器初始化的时候执行该方法。 从Java EE5规范开始&#xff0c;Servlet中增加了两个影响Servlet生命周期的注解…

精准水位在流批一体数据仓库的探索和实践

作者 | 浮生若梦的石头 导读 随着实时计算技术在大数据中的广泛应用&#xff0c;数据的时效性得到大幅度&#xff0c;但是实际应用场景中&#xff0c;除了时效性&#xff0c;还面临着更高的技术要求。 本文结合实时计算的水位技术在流批一体数据仓库中的探索和实践&#xff0c;…

elementUI使用

一&#xff1a;elementUI下拉框错位 下图为错位示例 使用如下方法&#xff0c;可解决错位问题 // 在模板文件中&#xff0c;配置不让组件插入body中 <el-select:popper-append-to-body"false"> // 使用决定定位&#xff0c;强制下拉选项放在下拉框下方且对齐。…

一键卸载流氓垃圾软件,这2款软件让电脑干净无弹窗

​你是否因为不知道怎么卸载流氓垃圾软件而崩溃&#xff1f;你是否在为不知从何而来的广告弹窗而抓狂&#xff1f;很多小伙伴表示&#xff0c;电脑联网就疯狂弹窗&#xff0c;还莫名其妙下载了很多软件。今天教你一键卸载流氓垃圾软件&#xff0c;告别弹窗&#xff0c;还你一个…

2.5 数据部分总结

2.5 数据部分总结 李沐 B站&#xff1a;https://space.bilibili.com/1567748478/channel/collectiondetail?sid28144 课程主页&#xff1a;https://c.d2l.ai/stanford-cs329p/ 1. 数据方面的挑战&#xff1a; 数据量和标注质量的权衡&#xff1a; ​ 在数据方面也会有挑战&a…

3月31号 上午 数据结构课程中 引出的几个算法题目

T1:约瑟夫游戏-- 剑指 Offer 62. 圆圈中最后剩下的数字&#xff1a; 0,1,,n-1这n个数字排成一个圆圈&#xff0c;从数字0开始&#xff0c;每次从这个圆圈里删除第m个数字&#xff08;删除后从下一个数字开始计数&#xff09;。求出这个圆圈里剩下的最后一个数字。 例如&…

[Few-shot learning] Siamese neural networks

这篇文章主要介绍的是Siamese Neural Network经典论文&#xff1a; Gregory Koch, et al., Siamese Neural Networks for One-shot Image Recognition. ICML 2015。 神经网络能够取得非常好的效果得益于使用大量的带标签数据进行有监督学习训练。但是这样的训练方法面临两个难题…

【Unity入门】资源包导入和导出

【Unity入门】资源包导入和导出 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;1&#xff09;资源目录 Unity的资源&#xff08;模型&#xff0c;场景&#xff0c;脚本&#xff09;等都保存在Assert目录下&…

Python中进程和线程到底有什么区别?

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 一、进程和线程的关系 线程与进程的区别可以归纳为以下4点&#xff1a; 地址空间和其它资源&#xff08;如打开文件&#xff09;&#xff1a;进程间相互独立&#xff0c;同一进程的各线程间共享。…

2023爱分析 · 认知智能厂商全景报告 | 爱分析报告

报告编委 黄勇 爱分析合伙人&首席分析师 李进宝 爱分析高级分析师 陈元新 爱分析分析师 目录 1. 研究范围定义 2. 市场洞察 3. 厂商全景地图 4. 市场分析与厂商评估 5. 入选厂商列表 1. 研究范围定义 研究范围 人工智能的发展分为三个阶段——计算…

【C++】类和对象(中)—构造函数|析构函数|拷贝构造|赋值重载

类和对象&#xff08;中&#xff09;一、类的6个默认成员函数二、构造函数☀️构造函数概念☀️构造函数特性三、析构函数❄️析构函数的概念❄️析构函数的特性小总结四、拷贝构造&#x1f30d;拷贝构造概念&#x1f30d;拷贝构造特性五、赋值运算符重载&#x1f318;运算符重…

基于sprinmgboot实现实习管理系统的设计【源码+论文】

基于sprinmgboot实习管理系统的设计与实现演示摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;实习管理也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管…

环境搭建:使用python matplotlib画图不显示中文问题解决

1.背景 python matplotlib.plt 使用 plt.title 写标题时&#xff0c;标题显示为方框&#xff0c;无法正常显示中文&#xff0c;而且基本上在一台新的服务器上配置python开发环境都会遇到这种问题&#xff0c;因此写个文章记录一下。 画图不显示中文的问题如下&#xff1a; 2…
最新文章