中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

JavaScript中異步編程的示例分析

這篇文章給大家分享的是有關(guān)JavaScript中異步編程的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

創(chuàng)新互聯(lián)建站長期為上1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為北戴河企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè),北戴河網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

目的

  • 提升開發(fā)效率,編寫易維護(hù)的代碼

引子問題

  • 請求時候為什么頁面卡死??

$.ajax({
  url: "www.xx.com/api",
  async: false, // true
  success: function(result) {
    console.log(result);
  },
});
  • 為什么數(shù)據(jù)更新了,DOM 卻沒有更新??

// 異步批量更新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
  },
});

產(chǎn)生異步的原因

原因:單線程(一個時間點,只做一件事),瀏覽器的 JS 引擎是單線程導(dǎo)致的。

單線程是指在 JS 引擎中負(fù)責(zé)解釋和執(zhí)行 IavaScript 代碼的線程只有一個,不妨叫它主線程。

所謂單線程,就是指一次只能完成一件任務(wù)。如果有多個任務(wù),就必須排隊,前面一個任務(wù)完成再執(zhí)行后面一個任務(wù)。

先看看一下瀏覽器內(nèi)核的線程圖:

JavaScript中異步編程的示例分析

其中,渲染線程和 JS 線程互斥。

假設(shè)有兩個函數(shù),一個修改一個刪除,同時操作一個 DOM 節(jié)點,假如有多個線程的話,兩個線程一起執(zhí)行,肯定就死鎖了,就會有問題。

為什么 JS 要設(shè)計為單線程,因為瀏覽器的特殊環(huán)境。

單線程的優(yōu)缺點:

這種模式的好處是實現(xiàn)起來比較簡單,執(zhí)行環(huán)境相對單純;壞處是只要有一個任務(wù)耗時很長,后面的任務(wù)都必須排隊等著,會拖延整個程序的執(zhí)行。常見的瀏覽器無響應(yīng)(假死),往往就是因為某一段 Javascript 代碼長時間運(yùn)行(比如死循環(huán)),導(dǎo)致整個頁面卡在這個地方,其他任務(wù)無法執(zhí)行。

常見的堵塞(死循環(huán)):

while (true) {}

JS 在設(shè)計之初就以運(yùn)行在瀏覽器中的腳本語言,所以也不想搞得這么復(fù)雜,就設(shè)計成了單線程,也就是,一個時間點,只能做一件事。

為了解決單線程堵塞這個缺點:產(chǎn)生了異步。

拿吃泡面舉例:

  • 同步:買泡面=》燒水(盯著)=》煮面=》吃泡面

  • 異步:買泡面=》燒水(水開了熱水壺響-回調(diào))=》看電視=》煮面(面好了熱水壺響-回調(diào))=》看電視=》熟了叫我=》吃泡面

看電視就是異步操作,熱水壺響,就是回調(diào)函數(shù)。

異步編程

JS 中大多的代碼都是同步執(zhí)行的,只有極個別的函數(shù)是異步執(zhí)行的,異步執(zhí)行的代碼,則需要異步編程。

異步代碼

setTimeout(() => {
  console.log("log2");
}, 0);
console.log("log1");
// ?? log1 log2

異步代碼的特點:不是立即執(zhí)行,而是需要等待,在未來的某一個時間點執(zhí)行。

同步代碼異步代碼
<script>代碼網(wǎng)絡(luò)請求(Ajax)
I/O 操作定時器(setTimeout、setInterval)
渲染操作Promise(then)

async/await

回調(diào)函數(shù)

異步代碼最常見的寫法就是使用回調(diào)函數(shù)。

  • HTTP 網(wǎng)絡(luò)請求(請求成功、識別后執(zhí)行 xx 操作)

  • DOM 事件綁定機(jī)制(用戶觸發(fā)事件后執(zhí)行 xx 操作)

  • 定時器(setTimeout、setInterval)(在達(dá)到設(shè)定時間后執(zhí)行 xx 操作)

// 注意到click方法中是一個函數(shù)而不是一個變量
// 它就是回調(diào)函數(shù)
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});
// 或者
function click() {
  // 它就是回調(diào)函數(shù)
  alert("Btn 1 Clicked");
}
$("#btn_1").click(click);

回調(diào)函數(shù)的缺點也很明顯,容易產(chǎn)生回調(diào)地獄:

JavaScript中異步編程的示例分析

異步編程的三種方式

  • callback

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);
}

在線預(yù)覽

預(yù)覽地址:http://jsrun.net/s43Kp/embedded/all/light

問題??

如果多個異步代碼同時存在,那么執(zhí)行順序應(yīng)該是怎樣的?那個先執(zhí)行、那個后執(zhí)行了?

宏任務(wù)和微任務(wù)

異步代碼的劃分,異步代碼分宏任務(wù)和微任務(wù)。

宏任務(wù)(不著急)微任務(wù)(著急)
<script>整體代碼Promise
setTimeout/setInterval

事件循環(huán)(Event loop)

JavaScript中異步編程的示例分析

執(zhí)行順序:

  • 執(zhí)行整體代碼<script>(宏任務(wù))

  • 執(zhí)行所有微任務(wù)

  • 執(zhí)行一個宏任務(wù)

  • 執(zhí)行渲染線程

  • 2->3->2->3...依次循環(huán)(在 2、3 步中又創(chuàng)建了新的宏、微任務(wù))

重復(fù)從宏任務(wù)和微任務(wù)隊列里拿出任務(wù)去執(zhí)行。

總結(jié)

因為瀏覽器設(shè)計的原因,JS 線程和渲染線程互斥,所以 JS 線程被設(shè)計成了單線程。

因為單線程執(zhí)行一些操作(如網(wǎng)絡(luò)請求)時有堵塞的問題,所有產(chǎn)生了異步。

因為有了異步,所以產(chǎn)生了異步編程,從而有了回調(diào)函數(shù)。

因為回調(diào)函數(shù)寫多了會產(chǎn)生回調(diào)地獄,所有又有了解決回調(diào)地獄的 Promise 寫法

自 ES7 標(biāo)準(zhǔn)后有了比 Promise 更加優(yōu)雅的寫法 ———— async/await 寫法,也是異步編程的最終解決方法。

因為 JS 的代碼分為同步和異步代碼,同步代碼的執(zhí)行順序不必多說,自上而下的執(zhí)行。

但是如果有多個異步的代碼,他的執(zhí)行順序又是怎么的呢??

為了解決多個異步代碼的執(zhí)行順序問了,有了事件循環(huán)(EventLoop),將異步任務(wù)區(qū)分為宏任務(wù)、微任務(wù),依據(jù)規(guī)則依次執(zhí)行。

至此 完!

練習(xí)

console.log("script start");
setTimeout(function() {
  console.log("timeout1");
}, 10);
new Promise((resolve) => {
  console.log("promise1");
  resolve();
  setTimeout(() => console.log("timeout2"), 10);
}).then(function() {
  console.log("then1");
});
console.log("script end");

寫出 log 的輸出結(jié)果,并說出理由。

感謝各位的閱讀!關(guān)于“JavaScript中異步編程的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

文章題目:JavaScript中異步編程的示例分析
轉(zhuǎn)載源于:http://m.2m8n56k.cn/article34/iesope.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計服務(wù)器托管、網(wǎng)站策劃、定制開發(fā)商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司
主站蜘蛛池模板: 欧美日本高清视频在线观看 | 欧美成人毛片免费网站 | 美女黄色在线 | 中文字幕在线成人免费看 | 亚洲精品久久久午夜伊人 | 欧美精品久久久久久久久大尺度 | 亚洲午夜影视 | 亚洲国产欧美国产综合一区 | 精品国产呦系列在线看 | 免费一级毛片在线播放不收费 | 免费看欧美一级特黄a大片一 | 一本久道久久综合婷婷五 | 黑人一级黄色片 | gogo999亚洲肉体艺术大胆 | 手机看片国产免费久久网 | 日韩欧美一区二区三区不卡视频 | 国产日产高清欧美一区二区三区 | 国产成人精品免费视频 | 国产精品高清全国免费观看 | 久久久久视频精品网 | 99久久精品免费看国产免费软件 | 国产欧美另类久久久精品免费 | 国产亚洲精品美女一区二区 | 521a久久九九久久精品 | 最新国产美女一区二区三区 | 日本欧美一级二级三级不卡 | 三毛片| 久草网视频在线 | 在线观看国产一区二区三区99 | 色婷婷久久综合中文久久蜜桃 | 亚洲观看视频 | 久操免费在线 | 成人午夜在线播放 | 亚洲专区在线视频 | 色偷偷亚洲第一成人综合网址 | 午夜久久影院 | 日本亲子乱子伦视频 | www女人| 日本特黄特色免费大片 | 日本久久久久久 | 福利视频在线午夜老司机 |