JS是单线程的语言,也就是说同一时间只会执行一行程序,所以如果一段程序执行过久就会造成阻塞(blocking)的现象,必须等到它结束后才能执行下一段程序。
举个例子来说,如果我们今天要买便当,但是老板说要十分钟才会好,那难道我们这十分钟内都不能做任何事情吗?
当然不是,JS本身有非同步执行的功能,也是就说我们会先跟这个函式说,你先到旁边继续跑,好了在「回来呼叫」我,我先继续跑其他程序。
有没有看到熟悉的关键字「回来呼叫」,没错非同步执行基本上都是利用callback达成。
举个例子来说,我们今天想要某个函式两秒后在执行,可以这样写:
function funA(){
console.log(“funA”);
}
function funB(){
console.log(“funB”);
}
setTimeout(funA,2000);
funB();
//funB
//funA
但是callback作非同步会发现有一个问题,假设我们今天要:
监听一个按钮
点击后延迟一秒
向API发送请求(wowgoldfine)
btn.addEventListener(“click”,function(){
setTimeout(function(){
var oReqSec = new XMLHttpRequest();
var url = 'https://devche.com/api/speech/data';
oReqSec.addEventListener(“load”,functiion(){
if(this.resp onseText){
console.log('success');
}
});
oReqSec.open(“GET”,url);
oReq.send();
},1000);
})
有注意到,那恐怖的巢状结构了吗?这个我们通常称为回呼地狱(callback hell)。
但是其可怕之处并不是在于巢状结构,而是在于如果其中一个callback出了问题,不论是自己还是别人都难以debug。
这个例子或许比较不好懂,那我们换一个简单的来看:
doA(function(){
doB()
doC(function(){
doD(function(){
doE();
})
})
})
当今天里面有个非同步函式出问题的话,有办法在短时间内找到吗?
肯定是没有办法的吧!
所以很多人都会拿这张波动拳图片来戏称回呼地狱
那到底要怎么解决这个问题呢?
JS在ES6时候提出了Promise语法,虽然底层还是用callback,但却大大解决了这个回呼地狱的问题。
至于怎么做?我们会在明天一一解析。(yfxj.net)