本篇文章帶大家了解JavaScript中的非同步程式設計。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
異步,就是非同步....
這節內容可能會有點枯燥,但是卻是JavaScript 中非常重要的概念,非常有必要去學習。
$.ajax({ url: "www.xx.com/api", async: false, // true success: function(result) { console.log(result); }, });
// 异步批量更新DOM(vue-nextTick) // <p id="app">{{num}}</p> new Vue({ el: "#app", data: { num: 0, }, mounted() { let dom = document.getElementById("app"); while (this.num !== 100) { this.num++; } console.log("Vue num=" + this.num, "DOM num=" + dom.innerHTML); // Vue num=100,DOM num=0 // nextTick or setTimeout }, });
原因:單一線程(一個時間點,只做一件事),瀏覽器的JS 引擎是單線程導致的。
單執行緒是指在 JS 引擎中負責解釋和執行 IavaScript 程式碼的執行緒只有一個,不妨叫它主執行緒。
所謂單線程,就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成再執行後面一個任務。
先來看看瀏覽器核心的執行緒圖:
#其中,渲染執行緒與JS 執行緒互斥 。
假設有兩個函數,一個修改一個刪除,同時操作一個 DOM 節點,假如有多個執行緒的話,兩個執行緒一起執行,肯定就死鎖了,就會有問題。
為什麼 JS 要設計為單線程,因為瀏覽器的特殊環境。
單一執行緒的優缺點:
這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是只要有一個任務耗時很長,後面的任務都必須排隊等著,會拖延整個程式的執行。常見的瀏覽器無回應(假死),往往是因為某一段 Javascript 程式碼長時間運行(例如死循環),導致整個頁面卡在這個地方,其他任務無法執行。
常見的堵塞(死循環):
while (true) {}
JS 在設計之初就以運行在瀏覽器中的腳本語言,所以也不想搞得這麼複雜,就設計成了單線程,也就是,一個時間點,只能做一件事。
為了解決單執行緒阻塞這個缺點:產生了非同步。
拿吃泡麵舉例:
看電視就是非同步操作,熱水壺響,就是回呼函數。
JS 中大多的程式碼都是同步執行的,只有極個別的函數是非同步執行的,非同步執行的程式碼,則需要非同步程式設計。
setTimeout(() => { console.log("log2"); }, 0); console.log("log1"); // ?? log1 log2
非同步程式碼的特點:不是立即執行,而是需要等待,在未來的某一個時間點執行。
同步程式碼 | #非同步程式碼 |
---|---|
<script></script> 程式碼 |
網路請求(Ajax) |
I/O 操作 | 計時器(setTimeout、setInterval) |
渲染操作 | Promise(then) |
回呼函數
// 注意到click方法中是一个函数而不是一个变量 // 它就是回调函数 $("#btn_1").click(function() { alert("Btn 1 Clicked"); }); // 或者 function click() { // 它就是回调函数 alert("Btn 1 Clicked"); } $("#btn_1").click(click);
function getOneNews() { $.ajax({ url: topicsUrl, success: function(res) { let id = res.data[0].id; $.ajax({ url: topicOneUrl + id, success: function(ress) { console.log(ress); render(ress.data); }, }); }, }); }
promise
function getOneNews() { axios .get(topicsUrl) .then(function(response) { let id = response.data.data[0].id; return axios.get(topicOneUrl + id); }) .then((res) => { render(res.data.data); }) .catch(function(error) { console.log(error); }); }async/await
async function getOneNews() { let listData = await axios.get(topicsUrl); let id = listData.data.data[0].id; let data = await axios.get(topicOneUrl + id); render(data.data.data); }
預覽網址:http://jsrun.net/s43Kp/embedded/all/ light | 問題? ?如果多個非同步程式碼同時存在,那麼執行順序應該是怎麼樣的?那個先執行、那個後執行了? |
---|---|
非同步程式碼的劃分,非同步程式碼分宏任務和微任務。
|
|
#微任務(急) |
以上是手把手帶你去理解JavaScript中的非同步編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!