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)