激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - JS異步的執行原理和回調詳解

JS異步的執行原理和回調詳解

2022-02-13 17:24Zxinxxxx js教程

這篇文章主要給大家介紹了關于JS異步的執行原理和回調的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、JS異步的執行原理

  我們知道JavaScript是單線程的,而瀏覽器是多線程的。單線程執行任務需要一個個排隊進行,假如一個任務需要很長時間執行(像ajax需要較長時間),會直接導致無響應,后面的任務一直在等待執行。這時候就需要用到異步。

  想了解異步,首先我們要知道瀏覽器有最基本的三個常駐線程: JS引擎線程,事件觸發線程,GUI渲染線程。

  其中JS引擎線程和事件觸發線程共同構成了一種事件循環機制,而GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新保存在一個隊列中,當JS引擎空閑時,立即被執行。

  我們從它的事件循環機制解析:

JS異步的執行原理和回調詳解

  JS引擎線程中分為同步和異步任務:

    1.同步任務全部通過主線程執行,形成執行棧。

    2.當有異步任務時交給異步進程(WebAPIs):包含事件觸發線程或者定時器線程等處理,形成任務隊列。

    3.當執行棧中的任務全部處理完成,主線程為空閑的時候,會從任務隊列中提取任務到執行棧中執行。

  通俗來說,JavaScript除了主線程之外還存在一個任務隊列,任務隊列存放需要異步執行的內容,執行完主線程后,就會不斷循環掃描執行任務隊列的任務,直至隊列清空。

畫解:

JS異步的執行原理和回調詳解

  如圖小明因為學習耗時長會,如果沒做完就會一直無法玩DNF游戲了,就把學習放到了異步任務隊列中,等玩完游戲(主線程)再學習(任務隊列)。期間母親添加學習事件(DOM事件),小明每完成一個學習任務就看看還有啥任務(循環掃描),直至最后做完.

  下面再看一個例子(瀏覽器刷新不斷點擊按鈕):

  let myData = null
  //ajax請求
  function ajax() {
  //騰訊新冠實時數據接口,僅做學習
  axios.get("https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=chinaDayList,chinaDayAddList,nowConfirmStatis,provinceCompare")
   .then(data => {
   console.log("ajax返回成功");
   myData = data.data
   console.log(myData);

   })
   .catch(error => {
   console.log("ajax返回失敗");
   })
  }
  console.log(myData);
  ajax()
  setTimeout(() => {
  console.log("定時器");
  }, 2000);
  console.log(myData);
  const btn = document.querySelector("button")
  btn.onclick = () => {
  console.log("點擊了");
  }

null
null
ajax返回成功
Object
點擊了
定時器
點擊了

  可以看到,console在主線程中是同步執行的,先執行,而在主線程外的任務隊列,存放著異步執行的內容,這里是setTimeout,ajax和DOM事件,按照任務隊列順序執行(循環掃描隊列)。

  為什么要循環掃描呢?

  通過點擊事件可以看出,當用戶進行交互時(點擊事件,滾動事件,窗口大小變化事件等),會向事件循環中的任務隊列添加新事件,然后等待執行,所以需要循環掃描。

二、JS異步中的回調

  既然異步都是放在最后的任務隊列執行,那么我們很多邏輯就難以實現,這時候我們需要處理這種異步邏輯,最常用的方式是回調――回頭調用。

回調函數:簡單來說就是,函數A中傳入函數B作為參數時,函數B即為A函數執行的回調函數。回調有嵌套回調和鏈式回調兩種。

  下面是回調的一個簡單用法:

   let myData = null
   console.log(myData);
   setTimeout(() => {
    console.log("定時器");
   }, 2000);
   const btn = document.querySelector("button")
   btn.onclick = () => {
    console.log("點擊了");
   }
   let name = "張三"
   function hr(callback) {
    setTimeout(() => {
     console.log(`我是${name}`);
     callback();
    }, 2001);
   }
   console.log(myData);
   function gj() {
    console.log(`${name}你好,我是李四,認識一下吧`);
   }
   hr(gj)

null
null
點擊了
定時器
我是張三
張三你好,我是李四,認識一下吧
點擊了

  很明顯的看到,當我們函數需要用到數據的時候就用到了回調,這里用到的是異步回調。

  回調雖然是解決異步常用的方法,可是伴隨著JS日益復雜的需求。同步異步需要越來越多的回調實現邏輯。同異步的混雜和過多的回調嵌套和縮進使得代碼變得難以解讀和維護,形成“回調地獄”。

JS異步的執行原理和回調詳解

  我們看一個例子:

const verifyUser = function(username, password, callback){
  dataBase.verifyUser(username, password, (error, userInfo) => {
    if (error) {
      callback(error)
    }else{
      dataBase.getRoles(username, (error, roles) => {
        if (error){
          callback(error)
        }else {
          dataBase.logAccess(username, (error) => {
            if (error){
              callback(error);
            }else{
              callback(null, userInfo, roles);
            }
          })
        }
      })
    }
  })
};

大多數人光是看到上面的代碼就感受到了腦子凍結的滋味,如果一個項目里擁有上百個這樣的代碼塊,過一段時間,我相信連編寫他的人都會頭疼。來到自己的項目就像是來到了地獄。

  最主要的是,與此同時回調還存在信任問題,他把執行控制權交給了某個第三方(比如ajax)。為了解決信任問題,我們必須在程序寫各種邏輯來解決回調帶來的信任問題。

  ?調用過早

  ?調用過完

  ?調用次數過多過少,沒有把需要的參數成功傳給回調函數,

  ?可能出現的錯誤被吞。

  可以發現寫特定邏輯來解決特定的信任問題,已經使得難度大于本身應用價值了,還會造成代碼冗雜,可讀性差等問題。

  綜上:回調解決異步存在缺陷:

     1)不符合人對任務處理的邏輯思維

     2)回調帶來的信任問題。

  面對回調日益明顯的弊端,ES6更新了Promise用來解決異步問題。下一篇寫ES6――Promise。

總結

到此這篇關于JS異步的執行原理和回調的文章就介紹到這了,更多相關JS異步執行原理回調內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/Zxinxxx/article/details/114444890

延伸 · 閱讀

精彩推薦
  • js教程JS實現一個秒表計時器

    JS實現一個秒表計時器

    這篇文章主要為大家詳細介紹了JS實現一個秒表計時器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    yiran010100110152022-02-13
  • js教程JS 的 六種打斷點的方式,你用過幾種?

    JS 的 六種打斷點的方式,你用過幾種?

    Debugger 是前端開發很重要的一個工具,它可以在我們關心的代碼處斷住,通過單步運行來理清邏輯。而 Debugger 用的好壞與斷點打得好壞有直接的關系。...

    神光的編程秘籍7932021-12-16
  • js教程mapboxgl實現帶箭頭軌跡線的代碼

    mapboxgl實現帶箭頭軌跡線的代碼

    這篇文章主要介紹了mapboxgl實現帶箭頭軌跡線的代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    GIS兵器庫9322021-12-27
  • js教程JavaScript canvas實現跟隨鼠標移動小球

    JavaScript canvas實現跟隨鼠標移動小球

    這篇文章主要為大家詳細介紹了JavaScript canvas實現跟隨鼠標移動小球,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    清靜清源10522022-01-20
  • js教程利用 JavaScript 實現并發控制的示例代碼

    利用 JavaScript 實現并發控制的示例代碼

    這篇文章主要介紹了利用 JavaScript 實現并發控制的示例代碼,本文通過實例代碼給大家介紹的非常想詳細,對大家的學習或工作具有一定的參考借鑒價值,需...

    descire3902021-12-23
  • js教程微信小程序自定義膠囊樣式

    微信小程序自定義膠囊樣式

    這篇文章主要為大家詳細介紹了微信小程序自定義膠囊樣式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    四曦11512021-12-21
  • js教程在HTML中使用JavaScript的兩種方法

    在HTML中使用JavaScript的兩種方法

    這篇文章主要介紹了在HTML中使用JavaScript的兩種方法,幫助大家更好的理解和制作網頁,感興趣的朋友可以了解下...

    itbsl9432021-12-18
  • js教程javascript實現隨機抽獎功能

    javascript實現隨機抽獎功能

    這篇文章主要為大家詳細介紹了javascript實現隨機抽獎功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    彴兗7142021-12-23
主站蜘蛛池模板: 国产精品视频2021 | 圆产精品久久久久久久久久久 | 国产亚洲精品久久久久久久久久 | 亚洲男人一区 | 羞羞视频一区二区 | 国产美女视频一区二区三区 | 精品一二三区视频 | 欧美精品一区二区久久 | 亚洲第一成人在线 | 成人免费在线观看视频 | 激情亚洲一区二区 | 日本逼逼视频 | 色阁五月 | 色婷婷av一区二区三区久久 | 欧美日韩高清一区二区三区 | 一级大片在线观看 | 性生活视频软件 | 国产一级二级毛片 | 国产在线精品一区二区三区 | 国产大片中文字幕在线观看 | 日本成年免费网站 | 午夜视频在线观看免费视频 | 色播一区| 成人欧美日韩一区二区三区 | 美女黄影院 | 国产精品亚洲一区二区三区在线观看 | 深夜精品福利 | 欧美成网站 | 日韩精品中文字幕一区二区 | 免费看污视频在线观看 | 久久夜夜视频 | 娇妻被各种姿势c到高潮小说 | www日韩大片 | 日韩av成人| 久久久人 | 毛片视频网站 | 成人aaaaa片毛片按摩 | 人人看人人舔 | 国产成人综合在线视频 | 日本网站在线播放 | 一区二区三区欧洲 |