异步流程控制 遍历篇groupBy

Posted 神奇大叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步流程控制 遍历篇groupBy相关的知识,希望对你有一定的参考价值。

文章目录

基础方法

arrayEachValue

function arrayEachValue(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(value));
    
   else 
    while (++index < size) 
      value = array[index];
      iterator(value, createCallback(value));
    
  

baseEachValue

function baseEachValue(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(value));
    
   else 
    while (++index < size) 
      value = object[keys[index]];
      iterator(value, createCallback(value));
    
  

symbolEachValue

function symbolEachValue(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(value));
    
   else 
    while ((item = iter.next()).done === false) 
      index++;
      value = item.value;
      iterator(value, createCallback(value));
    
  
  return index;

timesSync

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



异步遍历

groupBy

基本使用

var order = [];
var array = [4.2, 6.4, 6.1];
var iterator = function(num, done) 
  setTimeout(function() 
    order.push(num);
    done(null, Math.floor(num));
  , num * 10);
;
async.groupBy(array, iterator, function(err, res) 
  console.log(res); //  '4': [4.2], '6': [6.1, 6.4] 
  console.log(order); // [4.2, 6.1, 6.4]
);

实现

var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue);

function createGroupBy(arrayEach, baseEach, symbolEach) 
  return function groupBy(collection, iterator, callback) 
    callback = callback || noop;
    var size;
    var completed = 0;
    var result = ;

    if (isArray(collection)) 
      size = collection.length;
      arrayEach(collection, iterator, createCallback);
     else if (!collection) 
     else if (iteratorSymbol && collection[iteratorSymbol]) 
      size = symbolEach(collection, iterator, createCallback);
      size && size === completed && callback(null, result);
     else if (typeof collection === obj) 
      var keys = nativeKeys(collection); // Object.keys
      size = keys.length;
      baseEach(collection, iterator, createCallback, keys);
    
    if (!size) 
      callback(null, );
    

    function createCallback(value) 
      var called = false;
      return function done(err, key) 
        if (called) 
          throwError();
        
        called = true;
        if (err) 
          callback = once(callback);
          callback(err, objectClone(result)); // objectClone 浅拷贝
          return;
        
        var array = result[key];
        if (!array) 
          result[key] = [value];  // 按照callback传入的值进行分类,将数组元素存入
         else 
          array.push(value);
        
        if (++completed === size)  // 所有任务结束后返回分类结果
          callback(null, result);
        
      ;
    
  ;

groupByLimit

  • 限制每次处理异步任务数量
function groupByLimit(collection, limit, iterator, callback) 
  callback = callback || noop;
  var size, index, key, value, keys, iter, item, iterate;
  var sync = false;
  var started = 0;
  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 || isNaN(limit) || limit < 1) 
    return callback(null, result);
  
  timesSync(limit > size ? size : limit, iterate);

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

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

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

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

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

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

  function createCallback(value) 
    var called = false;
    return function(err, key) 
      if (called) 
        throwError();
      
      called = true;
      if (err) 
        iterate = noop;
        callback = once(callback);
        callback(err, objectClone(result));
        return;
      
      var array = result[key];
      if (!array) 
        result[key] = [value];
       else 
        array.push(value);
      
      if (++completed === size) 
        callback(null, result);
       else if (sync) 
        nextTick(iterate);
       else 
        sync = true;
        iterate();
      
      sync = false;
    ;
  

groupBySeries

  • 串行任务
function groupBySeries(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, result);
  
  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() 
    value = collection[keys[completed]];
    iterator(value, done);
  

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

  function done(err, key) 
    if (err) 
      iterate = throwError;
      callback = onlyOnce(callback);
      callback(err, objectClone(result));
      return;
    
    var array = result[key];
    if (!array) 
      result[key] = [value];
     else 
      array.push(value);
    
    if (++completed === size) 
      iterate = throwError;
      callback(null, result);
     else if (sync) 
      nextTick(iterate);
     else 
      sync = true;
      iterate();
    
    sync = false;
  

Node.js异步流程控制

以上是关于异步流程控制 遍历篇groupBy的主要内容,如果未能解决你的问题,请参考以下文章

Node.js异步流程控制

珠峰培训node正式课笔记 -- async任务流程控制,异步流程控制

async异步流程控制神器

如何在飞镖中控制异步执行流程[重复]

控制异步回调利器 - async 串行series,并行parallel,智能控制auto简介

JS基础 流程控制