-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
async2.6.1源码分析之parallel #27
Comments
参数为Object类型主要区别在于 var eachOfGeneric = doLimit(eachOfLimit, Infinity); // 控制并发的数量
function doLimit(fn, limit) {
return (iterable, iteratee, cb) => fn(iterable, limit, iteratee, cb)
}
function eachOfLimit(coll, limit, iteratee, callback) {
_eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
}
function _eachOfLimit(limit) => {
return (obj, iteratee, callback) => {
callback = once(callback || noop);
if (limit <= 0) {
throw new RangeError('concurrency limit cannot be less than 1')
}
if (!obj) {
return callback(null);
}
var nextElem = _iterator(obj); // 获取要执行的task
var done = false; // 任务队列是否退出
var canceled = false; // 如果其中一个err===false,就停止后面的task,已经在执行栈中的task会继续执行,未加入的task不会再执行了,且已经执行的result无效了,因为callback
var running = 0; // 并行运行的标志,当达到limit限制的时候,就停下来。当前一个task执行完一个,就执行下一个task,并不是说:limit=3时,就等待三个全部执行完再接着执行下一轮循环的三个
var looping = false; // 是否继续再次执行replenish函数,当limit===Infinity,此标志无效
function iterateeCallback(err, value) {
if (canceled) return
running -= 1; // task执行完,执行栈减1
if (err) {
done = true;
callback(err);
}
else if (err === false) {
done = true;
canceled = true;
}
else if (value === breakLoop || (done && running <= 0)) {
done = true;
return callback(null);
}
else if (!looping) {
replenish();
}
}
function replenish () {
looping = true;
while (running < limit && !done) {
var elem = nextElem();
if (elem === null) {
done = true;
if (running <= 0) {
callback(null);
}
return;
}
running += 1; // task加入任务队列,执行栈加1
iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
}
looping = false;
}
replenish();
};
}
// 模拟实现一个iterator遍历器
function _iterator(coll) {
if (isArrayLike(coll)) {
return createArrayIterator(coll);
}
var iterator = getIterator(coll);
return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
}
function createArrayIterator(coll) {
var i = -1;
var len = coll.length;
return function next() {
return ++i < len ? {value: coll[i], key: i} : null;
}
}
function createES2015Iterator(iterator) {
var i = -1;
return function next() {
var item = iterator.next();
if (item.done)
return null;
i++;
return {value: item.value, key: i};
}
}
function createObjectIterator(obj) {
var okeys = obj ? Object.keys(obj) : [];
var i = -1;
var len = okeys.length;
return function next() {
var key = okeys[++i];
return i < len ? {value: obj[key], key} : null;
};
}
function isArrayLike(value) {
return value &&
typeof value.length === 'number' &&
value.length >= 0 &&
value.length % 1 === 0;
}
function getIterator(coll) {
return coll[Symbol.iterator] && coll[Symbol.iterator](); // coll instanceof Set/Map
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
分析参数为数组的情况
并行和并发的区别
看过代码之后,才发现不是真正意义上的
parallel
parallel功能和Promise.all方法一样
The text was updated successfully, but these errors were encountered: