异步流程控制 遍历篇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异步流程控制
原文地址:Node.js异步流程控制
以上是关于异步流程控制 遍历篇groupBy的主要内容,如果未能解决你的问题,请参考以下文章
珠峰培训node正式课笔记 -- async任务流程控制,异步流程控制