淺談前端與網路請求

不洗碗工作室發表於2017-12-11
作者:不洗碗工作室 - Michael Code

部落格地址:http://michaelcode.cn

版權歸作者所有,轉載請註明出處

toc: 前端

學前端也有一段時間了,想淺談一下前端與網路請求。談網路請求,自然繞不開的一個話題便是 JS。

作為前端三大基礎之一的 JavaScript ,其重要性是不言而喻的。

在一位前輩推薦下,機緣巧合遇到了廖雪峰老師的 JavaScript 教程,此教程有哪些好處,我就不廢話了,感興趣的朋友自己去看一下。 在一開始看這個教程的過程中,感覺學起來幾乎是毫無阻礙的,暗自高興遇到了福音,直到碰到了這三個詞:

JSONAjaxPromise
。其實,廖老師的教程中對此三者的詳述挺清楚的。然而,對於一個只會用 HTMLCSS 寫靜態頁面、從來沒接觸過非同步、網路請求等概念的小白來講,簡直像看到了幾個外星文字一樣。

為了搞清楚這三個神奇玩意兒的含義以及作用,我開始踏上了瘋狂的“百度谷歌之旅”。結果,為了解釋這三個詞,卻又搞出了一大堆更神奇的玩意兒。大致如下:

FetchGeneratorThunkasyncawait
。其實,如果學完這些的話,你會發現,這些概念其實根本不是平行的,甚至根本不在一個維度上。可是,這些概念對於當時的我來說,卻是混雜在一起的一鍋粥,越燉越亂。。。越亂。。。亂。。。

後來,在經歷了無數痛苦的掙扎之後。我終於能站在這裡,把這些概念一點點的撥弄清楚,談一談這到底是怎麼一回事。而且,我發現,當時不明白這些概念,最大的原因是把它們給割裂開了。所以,這篇文章將會把這些概念串聯起來,給你還原一個網路請求的全貌,另外,本文只理思路,不講細節實現。如果,你跟我當時一樣對以上這些概念一頭霧水,那麼,這篇文章應該是會對你學習有些幫助的,至少會讓你不那麼想自殺(開個玩笑了哈~)

  • 首先,我先來說一下,前端與網路請求的關係。

如果你是剛開始接觸前端,可能你不會了解網路請求相關的東西。可是,你總該聽過靜態頁面動態頁面這兩種概念吧,很可能,你聽某個前輩講過,動態頁面跟頁面上的動態不是一回事。比如說,我的這個部落格,雖然你點選一些地方,會有一些動畫效果,可它卻仍然是個靜態頁面。那麼,啥叫動態頁面呢?這就是前端跟網路請求的關係了,如果一個網頁在你使用的過程中,向伺服器發出了某些網路請求,並接收到了從伺服器返回來的資料(當然也可能請求失敗),那麼,這樣的網頁才叫做動態頁面。也就是說,這裡的動態指的是你的瀏覽器(客戶端)和伺服器(伺服器端)的資料交換。

作為一個真正的前端,所做的事就是負責從客戶端獲取使用者的資料(像是你填寫的使用者名稱和密碼),然後,把這些資料組織起來,發給伺服器端,然後等待伺服器端處理完資料(至於伺服器接收到資料怎麼處理,就是後端大佬的問題了),接收返回的資料,並對這些返回的資料進行不同的處理(比如展示在頁面上或者儲存起來之類的)。也就是說,寫出一個漂亮的頁面展示給別人只是前端工作的一部分(一開始,天真的我就以為前端就是寫寫頁面。。。)

  • 接下來,就對上面的幾個概念進行挨個解說

搞清楚了前端與網路請求的關係,解釋上面的幾個看上去玄之又玄概念就容易多了(這些概念基本都是用在上面的過程中)。再墨跡一遍,我這篇裡面側重的是對那些概念的個體理解和把握,並不會具體講它們的用法。

  1. JSON(用的最廣泛,也是最容易理解的一個概念): 首先, JSON 的本質是一種資料的格式,取代的是 XML 。那麼,這哥倆的作用是啥呢?其實就是一個傳輸功能,也就是在我們前邊所說的網路請求的傳輸過程中,資料的格式必須是JSON格式。所以, JSON 不止是前端要用的東西,後端在向前端傳輸資料的時候,同樣也得先把資料格式轉化成 JSON 格式,再進行傳輸。至於為啥要取代以前的 XML 格式,很好理解, JSON 格式簡單唄。

  2. AJAX: 其實,這四個字母是

    Asynchronous JavaScript and XML
    的縮寫,翻譯成中文就是:用JavaScript執行非同步網路請求。它的本質就是用來向伺服器端發出網路請求的一種方法。作用如上。那麼,非同步請求又是個啥意思?說白了,就是,在你發出請求後,你仍然能繼續去執行後面的程式碼,而不是乾等著,啥也幹不了(因為網路請求從發出到收到迴應是需要一定時間的,尤其你的網比較渣的時候)。等到伺服器端返回的資料到達客戶端時,你再停下手頭的活,去處理收到的資料。

  3. Promise: 前邊在 AJax 裡說到了非同步,而 Promise 就是一種執行非同步操作的方式(它在 ES6 裡有了規範的用法)。它的好處是啥呢?就是寫起來以及處理起來比較方便。當然,非同步操作不止在網路請求裡用得到,執行起來需要等待一定時間的操作,都可以而且是應該寫成非同步的操作,比如 Timeout 函式。這樣的話,等待時間得到了利用,珍惜時間嘛(當然,大部分情況下是考慮使用者體驗)。所以,Promise 不只是用在網路請求裡,所有用得到非同步的地方,它都可以大展身手。

  4. Fetch: 這個東西本質上是一種發出網路請求的方法。你傳給它一個 JSON 格式的物件、一種請求方法(如GET、POST)以及一個URL,它就會把這個 JSON 物件作為資料,傳輸給給定的 URL ,等著拿返回的資料。而且,這個神奇的東西在發完請求後,會返給你一個 Promise,這樣,你就不必再去額外地寫非同步了,而是在 Fetch 後邊直接跟一個非同步的處理(也就是接收到返回的資料該怎麼處理)。

  5. Generator: Generator是ES6裡面的新東西(其實ES6也不是很新了哈),是一個比較神奇的東西。它本質上來講,並不是一個函式,但它的執行卻跟函式很相似。它就相當於在函式裡打了許多斷點(yield),執行完一部分就停一下,等待繼續執行的命令。基於這樣的特性,我們把它的每次執行設定成自動化的,比如,在網路請求中,我們設定接收到返回的資料後,就繼續執行下面的操作,這樣,就相當於實現了一個網路請求的非同步操作。這樣的非同步操作,往往比較簡單方便。

  6. Thunk: Thunk 本質上來講,是一個函式,用來對非同步函式進行封裝,只留下一個引數--回撥函式。利用 Thunk 函式和 Generator 的結合,我們可以實現上面所說的 Generator 執行非同步操作。這也就是 Thunk 函式在網路請求中的作用。

  7. async和await: 這兩個東西是 ES7 裡面的新玩意兒,也是對非同步操作的簡化。其中的 async 用來標誌一個函式,就像 Generator 裡的*,而 await 就像 Generator 中的 yield 一樣。

至此前端與網路請求的概述以及相關的概念就介紹完了

儘管我已經盡力簡化了這些概念的定義,但一口氣看完了這麼多的概念,估計你還是會有點暈,所以,我在最後再把這些概念串一遍,畢竟,這才是初衷嘛。

前端網路請求的處理過程如下:

首先,利用 fetch(或者原始的 XMLHttpRequest ,這個東西跟 fetch 作用一樣)組織要發出的請求,並通過 Promise(或者Generator)(對應 XMLHttpRequest 的是 Ajax )實現非同步,接收到的資料是JSON 格式,然後再利用收到的資料進行進一步處理。

OK,本文到此就正式結束啦。如果你覺得有些頭暈迷糊,就緩一緩,再看一遍。或者,閉上眼,在腦海裡,想象一遍整個網路請求的過程。當然,讀完這篇,你只能理解個大概,具體怎麼寫,還要去看具體的教程或者文件的哈。

如果,本文幫助到了你,作者會很開心的。當然,你如果給點小費,作者會更開心喲。


相關文章