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

异步控制流程 遍历篇

文章目录

  • 基础方法
    • onlyOnce 只执行一次,第二次报错
    • once 只执行一次,第二次无效
    • iteratorSymbol 判断是否具有迭代器并返回迭代器
    • arrayEach 普通数组遍历
    • baseEach 对象类型遍历
    • symbolEach 具有迭代器类型遍历
  • 异步遍历
    • each

异步控制流程的目的:

  • 对异步操作提供类似同步遍历的操作
  • 本文的Promise兼容均为在原本只支持node回调的方式下修改

基础方法

onlyOnce 只执行一次,第二次报错

  • 只执行一次,因为第二次func变成了抛出错误
function onlyOnce(func) {return function(err, res) {var fn = func;func = throwError;fn(err, res);};
}

once 只执行一次,第二次无效

  • 只执行一次,因为第二次func变成了空函数
 function once(func) {return function(err, res) {var fn = func;func = noop;fn(err, res);};}

iteratorSymbol 判断是否具有迭代器并返回迭代器

var iteratorSymbol = typeof Symbol === func && Symbol.iterator;

arrayEach 普通数组遍历

- iterator:每次遍历的回调- callback:内部有个计数器,执行遍历完成后的回调function arrayEach(array, iterator, callback) {var index = -1;var size = array.length;// 三个参数情况if (iterator.length === 3) {while (++index < size) {// 传入value、key、手动计数最后遍历完成回调(只有第一次执行有效)iterator(array[index], index, onlyOnce(callback));}} else { // 两个参数情况while (++index < size) {iterator(array[index], onlyOnce(callback));}}
}

baseEach 对象类型遍历

function baseEach(object, iterator, callback, keys) {var key;var index = -1;var size = keys.length;// 三个参数情况if (iterator.length === 3) {while (++index < size) {key = keys[index];iterator(object[key], key, onlyOnce(callback));}} else { // 两个参数情况while (++index < size) {iterator(object[keys[index]], onlyOnce(callback));}}
}

symbolEach 具有迭代器类型遍历

  function symbolEach(collection, iterator, callback) {var iter = collection[iteratorSymbol]();var index = 0;var item;// 三个参数情况if (iterator.length === 3) {while ((item = iter.next()).done === false) {iterator(item.value, index++, onlyOnce(callback));}} else {// 两个参数情况while ((item = iter.next()).done === false) {index++;iterator(item.value, onlyOnce(callback));}}return index;}

异步遍历

each

  • 实现 forEach 效果
  • 原理:每次回调中执行计数器,判断计数完毕时,执行结束回调
exports.each=createEach(arrayEach, baseEach, symbolEach)function createEach(arrayEach, baseEach, symbolEach) {return function each(collection, iterator, callback) {let promise=new Promise((resolve,reject)=>{callback = once(callback || noop);var size, keys;var completed = 0;if (isArray(collection)) {size = collection.length;arrayEach(collection, iterator, done);} else if (iteratorSymbol && collection[iteratorSymbol]) {size = symbolEach(collection, iterator, done);size && size === completed && callback(null);} else if (typeof collection === obj) {// Object.keyskeys = nativeKeys(collection);size = keys.length;baseEach(collection, iterator, done, keys);}if (!size) {callback(null);reject('value should be an object');}function done(err, bool) {if (err) {callback = once(callback);callback(err);reject(err);} else if (++completed === size) {callback(null);resolve('null')} else if (bool === false) {callback = once(callback);callback(null);reject('cancel');}}})return promise.then((res)=>res).catch(err=> Promise.reject(err))};}

基本使用:

const array = { a: 1, b: 3, c: 2 };;
const iterator = function(key, value,done) {setTimeout(function() {done()// done() done只有第一次执行有效// done(err)、done(null,false) 结束遍历并执行最终回调}, key * 1000);
};// 回调方式
nac.each(array, iterator, function(err) {console.log('done')
});// Promise方式
async function neo(){try {let res=await nac.each(array, iterator);console.log('success',res);    } catch (error) {console.log('error',error)}}
http://www.lryc.cn/news/37560.html

相关文章:

  • ICASSP 2023论文模型开源|语音分离Mossformer
  • vs2019 更改工程项目名称
  • FusionCompute安装和配置步骤
  • makefile 参数和基本使用
  • golang 占位符还傻傻分不清?
  • manacher算法详解
  • 要做一个关于DDD的内部技术分享,记录下用到的资源,学习笔记(未完)
  • KDZD互感器二次负载测试仪
  • 在空投之后,Blur能否颠覆OpenSea的主导地位?
  • 2023年新三板产品及服务研究报告
  • 张力控制之开环模式
  • python的django框架从入门到熟练【保姆式教学】第二篇
  • 解决win10的过度保护导致文件下载不了程序不能打开运行
  • 扬帆优配|业务量大突破,这个行业发展明显向好
  • DJ1-4 计算机网络和因特网
  • Nginx根据$host及请求的URI规则重定向rewrite
  • 人工智能实验一:使用搜索算法实现罗马尼亚问题的求解
  • Spring Security基础入门
  • dnsresolver-limit
  • 使用 YoctoProject集成Qt6
  • 「媒体邀约」如何选择适合的媒体公关,媒体服务供应商
  • html2canvas和jspdf导出pdf,每个页面模块占一页,在pdf中垂直居中显示
  • 数学小课堂:集合论的公理化过程(用构建公理化体系的思路来构建自然数)
  • 3.10多线程
  • 缓存双写一致性之更新策略探讨
  • scala高级函数快速掌握
  • 手写模拟SpringMvc源码
  • 五分钟了解JumpServer V2.* 与 v3 的区别
  • 用友开发者中心应用构建实践指引!
  • snap使用interface:content的基础例子