1. 程式人生 > >學JS的心路歷程 -非同步執行

學JS的心路歷程 -非同步執行

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)