今天在学习koa2的时候发现本身对async的使用方法和原理都不是很熟悉,连带着发现本身对前端异步的解决方案并了解并不如何深入,因此干脆把前端现有的异步解决方案都复习了一遍。
今天先把将用callback和事件监听思想解决异步问题的代码贴出来,明天再补充代码的解析及其余解决方案;前端
function f1(f2) { setTimeout(function () { let b = 10; f2(b) }, 1000) } function f2(data) { console.log("callback_type_demo", data) } f1(f2);
这么写以后会于1s后再控制台打出 callback_type_demo 10。该方式容易理解,实际上就是是在f1执行完以后再调用f2,可是这个方法在多个异步操做嵌套的时候就变得很是难受。好比说这样:dom
function f1(f) { setTimeout(function () { let a = 10; setTimeout(function () { let b = a + 10; setTimeout(function () { let c = b + 10; setTimeout(function () { let d = c + 10; setTimeout(function () { let e = d + 10; f(e) }, 1000) }, 1000) }, 1000) }, 1000) }, 1000) } function finalF(data){ console.log('finalF',data) } f1(finalF);
代码执行完以后会于5s后打印出 finalF 50,多层嵌套以后该方法的语义就会开始不清晰,不容易理解与维护,而且在实际状况中,咱们还须要对借口返回的错误进行处理,那么这个写法就变得愈发的混乱和复杂,因此该方法是不可取的;koa
如下是我对 能够被监听事件的对象DOM 的实现,不想了解具体实现方式的能够跳过异步
//实现事件监听 /* DOM 能够被监听事件的对象 .on("eventName",function) 第一个参数为监听的事件名,第二个参数为 绑定 的方法 .removeOn("eventName",function) 第一个参数为监听的事件名,第二个参数为 解绑 的方法 .trigger("eventName") 参数接收事件名,触发该事件(并触发该事件绑定的全部方法) */ //具体实现能够不看,不影响对事件监听解决异步的理解 let DOM = function () { //被监听的事件的集合 let eventList = {}; //绑定事件监听的方法 this.on = function (eventName, fun) { if (typeof eventName !== "string") { console.error("监听的事件名应为字符串"); return; } if (typeof fun !== "function") { console.error("被触发的必须是事件"); return; } eventList[eventName] = eventList[eventName] || []; eventList[eventName].push(fun); }; //移除事件监听的方法 this.removeOn = function (eventName, fun) { let onList = eventList[eventName]; if (onList) { for (let i = 0; i < onList.length; i++) { if (onList[i] === fun) { onList.splice(i, 1); return } } } }; //触发事件监听的方法 this.trigger = function (eventName, param) { let onList = eventList[eventName]; if (onList) { for (let i = 0; i < onList.length; i++) { onList[i](param) } } }; };
接下来的是利用事件监听解决异步的方案,须要认真看的async
//生成两个DOM实例 let dom1 = new DOM(); let dom2 = new DOM(); //异步模拟 let f2 = function () { setTimeout(function () { console.log("开始触发事件:"); console.log("dom1 'done' 事件 触发:"); dom1.trigger('done', 20); console.log("dom2 'done' 事件 触发:"); dom2.trigger("done", "123"); }, 100); }; let f3 = function (data) { console.log("f3 run",data) }; //为dom1,dom2的'done' 事件绑定 f3 方法 console.log("dom1 On f3"); dom1.on("done", f3); console.log("dom1 On f3"); dom2.on("done", f3); f2(); setTimeout(function () { console.log("dom1 removeOn f3"); dom1.removeOn("done", f3); f2(); }, 200);
这里贴出该代码的运行日志
这里能够看到被绑定以后,第一次f2运行时,f3分别被dom1, dom2的'done'事件触发了;
可是在dom1解绑了f3以后,f2再次运行时,f3就只被dom2的‘done’事件触发了
事件监听模式不用关心被绑定的函数何时执行,咱们只须要在特定的时候触发对应的事件就能够了。同时这个模式也程序至关的依赖事件,变成事件驱动,运行流程会变得很不清晰。函数
今天的文章就写到这里了,都是本身学习的经历和理解,但愿你们多多斧正,多多关注,感谢学习