---
# System prepended metadata

title: 有關前端：前端非同步request

---


#  有關前端：前端非同步request


---
## 定義:

### 什麼是同步?
像是一個pipeline，同一時間一次做一件事情，就算有兩個人還是一件一件來，上一件完成了才會做下一件。很明顯的，出現了“閒置”的問題～

### 什麼是非同步？
雖然還是一個人一次只能做一件事情，但兩個人可以同時做事！

> 簡單來說，如果你去麥當勞點餐
> 同步的狀況是:
> 跟店員點了一份2號餐，點餐完收完錢，才開始下一步去做雙層牛肉吉士堡，再去裝薯條，再去裝飲料，再去一個一個放進紙袋裡面，才叫號取餐。
> 
> 相信這樣的工作方式，顧客肯定看得很著急XD
> 
> 非同步的情況就會是:
> 同樣跟店員點了一份二號餐，你還在確認附餐要甚麼的時候，第二位員工已經開始做雙層牛肉吉士堡了，等點完餐，同時有人去裝薯條有人去裝飲料，同時作業。



## 應用:
前端在寫 JavaScript 的時候有一個很常見的需求，那就是跟後端 API 串接拿取資料。假設我們有一個函式叫做getAPIResponse，就可以 call API 拿資料回來。


同步的版本會長得像這樣：
 ```Javascript
 // 假設有個發送 Request 的函式叫做 getAPIResponse
var result = getAPIResponse();
// 有可能等很久才被執行到
console.log(response);
```
**同步會發生什麼事？**

會阻塞後面的執行。
所以假設API Server規格很爛跑需要等 10 秒，整個JavaScript引擎都必須等10秒，才能執行下一個指令。
導致網頁會凍結!無法執行其他的action

*demo同步的例子*
```JavaScript
<script>
    var delay = 10000 // 凍結 10 秒
    var end = +new Date() + delay
    console.log('delay start')
    while(new Date() < end) {

    }
    console.log('delay end')
 </script>
```

but!!非同步那樣寫，怎麼去接result?
透過 Callback Function來知道要把result回傳到哪
**「當某事發生的時候，請利用這個 function 通知我」**

 ```Javascript
// 假設有個發送 Request 的函式叫做 sendRequest
// 額外宣告函式
function handleResponst() {
  console.log(response)
}
getAPIResponse(handleResponst)

// 比較常看到的匿名函式版本，功能跟上面完全一樣
getAPIResponse(function(err, response) {
  console.log(response)
})
```

優缺點
---
同步送出form時就向server傳送一個請求，然後server送回一個新的網頁:
1. 浪費頻寬
2. 回應時間依賴於伺服器的回應時間

非同步可以僅向伺服器傳送並取回必須的資料

優點:
* 用 JavaScript 處理回應，回應更快
* 不浪費資源

缺點:
* 如果同時多個非同步request，將無法保證哪一個需求先獲得伺服器的回應。
* solution: 自行處理或在JavaScript裡面動手腳以避免這類競爭問題的發生（如Ajax需求未回應之前，先disable送出按鈕），這又不必要的增加了程式設計師的負擔。



在非同步請求 (Asynchronous request) 還沒被開發之前，如果我們要瀏覽一則留言，就必須向 Server 重新 request 一個完整的頁面。等待頁面切換的這段時間畫面往往會卡住不動，直到接收 response，才會重新渲染 (render) 畫面。

而 Ajax 技術的出現，讓瀏覽器可以向 Server 請求資料而不需費時等待。當瀏覽器接收到 response 之後，新的內容就會即時地添入原本網頁。這也是為什麼當我們瀏覽 Facebook、Twitter 內容時，不會看見整個網頁一直重新整理。


AJAX
---
AJAX = Asynchronous JavaScript and XML
重點在於Asynchronous，***<font color="#f00">非同步</font>***。
Ajax 技術的出現，讓瀏覽器可以向 Server 請求資料而不需費時等待。當瀏覽器接收到 response 之後，新的內容就會即時地添入原本網頁。這也是為什麼當我們瀏覽 Facebook、Twitter 內容時，不會看見整個網頁一直重新整理。


可以以jQuery, Axios, fetch去實現~~



