我们习惯于使用传统的回调或事件处理来解决异步问题
事件:某个对象的属性是一个函数,当发生某一件事时,运行该函数
dom.onclick = function(){ }回调:运行某个函数以实现某个功能的时候,传入一个函数作为参数,当发生某件事的时候,会运行该函数。
dom.addEventListener("click", function(){ })本质上,事件和回调并没有本质的区别,只是把函数放置的位置不同而已。
一直以来,该模式都运作良好。
直到前端工程越来越复杂…
目前,该模式主要面临以下两个问题:
实例1
<div> <button id="btn1">按钮1:给按钮2注册点击事件</button> <button id="btn2">按钮2:给按钮3注册点击事件</button> <button id="btn3">按钮3:点击后弹出hello</button> </div> const btn1 = document.querySelector("#btn1"), btn2 = document.querySelector("#btn2"), btn3 = document.querySelector("#btn3"); btn1.addEventListener("click",()=>{ btn2.addEventListener('click',()=>{ btn3.addEventListener('click',()=>{ alert("hello") }) }) })实例2
/* 邓哥心中有三个女神 有一天,邓哥决定向第一个女神表白,如果女神拒绝,则向第二个女神表白,直到所有的女神都拒绝,或有一个女神同意为止 用代码模拟上面的场景 */ function biaobai(god, callback) { console.log(`邓哥向女神【${god}】发出了表白短信`); setTimeout(() => { if (Math.random() < 0.1) { //女神同意拉 //resolve callback(true); } else { //resolve callback(false); } }, 1000); } biaobai("女神1", function(result) { if (result) { console.log("女神1答应了,邓哥很开心!") } else { console.log("女神1拒绝了,邓哥表示无压力,然后向女神2表白"); biaobai("女神2", function(result) { if (result) { console.log("女神2答应了,邓哥很开心!") } else { console.log("女神2十分感动,然后拒绝了邓哥,邓哥向女神3表白"); biaobai("女神3", function(result) { if (result) { console.log("女神3答应了,邓哥很开心!") } else { console.log("邓哥表示生无可恋!!"); } }) } }) } })实例3 (json可自行编写)
//获取李华所在班级的老师的信息 ajax({ url: "./data/students.json?name=李华", success: function(data) { for (let i = 0; i < data.length; i++) { if (data[i].name === "李华") { const cid = data[i].classId; ajax({ url: "./data/classes.json?id=" + cid, success: function(data) { for (let i = 0; i < data.length; i++) { if (data[i].id === cid) { const tid = data[i].teacherId; ajax({ url: "./data/teachers.json?id=" + tid, success: function(data) { for (let i = 0; i < data.length; i++) { if (data[i].id === tid) { console.log(data[i]); } } } }) return; } } } }) return; } } } }) 异步之间的联系:某个异步操作要等待多个异步操作的结果,对这种联系的处理,会让代码的复杂度剧增