当前位置: 首页 > article >正文

异步流程控制 遍历篇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

相关文章:

  • 20250110_ PyTorch中的张量操作
  • 【json】
  • 计算机网络 (32)用户数据报协议UDP
  • istio-proxy oom问题排查步骤
  • 【LeetCode】力扣刷题热题100道(21-25题)附源码 接雨水 合并区间 字母异位词 滑动窗口 覆盖子串(C++)
  • Git:Cherry-Pick 的使用场景及使用流程
  • 【线程池的工作参数、什么情况下会触发最大线程数?什么情况下会回收线程?】
  • Java设计模式(十四)—— 模板方法模式
  • Mars3d项目启动上的一些坑
  • day2 操作系统考点
  • 程序猿成长之路之密码学篇-AES算法介绍
  • 【Gem5】有关gem5模拟器的资料导航
  • 计算机基本知识框架
  • JAVA电子招标采购系统源码—企业战略布局下的采购
  • Maven项目混淆、瘦身、打包exe
  • 排序 堆排序_57
  • Redis缓存击穿和穿透以及雪崩
  • Shell echo 命令
  • 代码随想录算法训练营第五十八天|739. 每日温度、496.下一个更大元素 I
  • 第二十七章 纹理总结
  • @PostConstruct注解
  • 精准水位在流批一体数据仓库的探索和实践
  • elementUI使用
  • 一键卸载流氓垃圾软件,这2款软件让电脑干净无弹窗
  • 2.5 数据部分总结
  • 3月31号 上午 数据结构课程中 引出的几个算法题目