JS異步方案

JS異步方案

單線程和event-loop

  1. 單線程:JS引擎線程只有一個,避免多線程DOM渲染沖突(GUI渲染線程互斥也是同理)

  2. 異步:解決JS單線程只能同時做一件事的問題,

  3. event-loop:主線程從任務隊列中讀取事件,這個過程是循環(huán)不斷的,實現(xiàn)異步的具體解決方案

callback

  1. 代碼演示:

    $.ajax({
        url: 'xxx',
        success: function(res => {
        
        })
    })
    

jquery的deferred

  1. 概念:jquery1.5版本之后ajax的實現(xiàn)就用的deferred,慢慢演變成promise

  2. ajax的變化, 鏈式操作,對拓展開放,對修改封閉

    // 1.5前
    var ajax = $.ajax({
        url: 'xxx',
        success: function(res => {}),
        error: function(err => {})
    })
    console.log(ajax)  // xhr對象
    
    // 1.5后
    var ajax = $.ajax('xxx');
    
    // ajax.reject() 可以直接篡改結果
    
    ajax.then(function() {
        // 完成  
    }, function() {
        // 失敗
    })
    .then(function() {
        // 完成2
    })
    console.log(ajax)  // 返回deferred對象
    
    
  3. 其他Deferred的promise

        function waitHandle() {
            var dtd = $.Deferred()
            var wait = function(dtd) {
                var task = function() {
                    // success
                    dtd.resolve()
                    //error
                    // dtd.reject()
                }
                // 異步操作
                setTimeout(task, 2000)
                // 返回Promise,而不是deferred對象
                return dtd.Promise()
            }
            return wait(dtd)
        }
        
        // 使用
        var w = waitHandle() // w接受的是promise對象
        
        // w.reject() 直接會報錯
        $.when(w)
        .then(res => {
           // 完成1
           return res
        }, (err) => {
            // 錯誤1
        })
        .then(res => {
            // 完成2
            return res
        })
    
  4. 總結

    1. deferred對象:結果可以直接被篡改(resolve, reject, done,then,fail)

    2. promise對象:不可被篡改(resolve, reject,then)

promise

  1. 代碼演示

        const loadImg = (src) => {
          return new Promise((resolve, reject) => {
            const img = document.createElement('img');
            img.onload = () => {
              resolve(img);
            }
            img.onerror = () => {
              reject('加載失敗');
            }
            img.src = src;
          })
        }
        // 異常捕獲
        loadImg('xxxx').then(res => {
            // 成功1
        })
        .then(res => {
            // 成功2
        })
        .catch(err => {
            // 統(tǒng)一捕獲異常,代碼報錯,reject返回錯誤都能捕獲
        })
    
  2. Promise.all

        // 異步任務全部執(zhí)行完,才能then
        const result1 = loadImg('xxxx');
        const result2 = loadImg('yyyy');
        Promise.all([result1, result2]).then(datas => {
            // datas是數組
            console.log(datas[0])
        })
    
  3. Promise.race

        // 只要有一個成功,就執(zhí)行then
        // result1, result2都是peomise對象
        Promise.race([result1, result2]).then(data => {
            // 最先完成promise的返回值
            console.log(data)
        })
    
  4. Promise標準(ES6)

    • 三種狀態(tài):pending,fulfilled,rejected
    • 狀態(tài)不可逆:pending -> fulfilled(成功),pending-> rejected(失?。?/li>

async-await

  1. async/await標準(ES7,需要babel-polyfill)

    • await必須包裹在 async 函數里面
    • await 后面可以追加promise對象, 獲取resolve的值
    • await 執(zhí)行返回的也是一個promise對象
    • try-catch可以捕獲 promise 中reject的值
  2. 代碼演示

        import 'babel-polyfill'; // ES7轉ES5
    
        const load = async function () {
            try {
                // 異步變成同步寫法,依次往下
                const result1 = await loadImg('xxx')
                console.log(result1)
                const result2 = await loadImg('yyy')
                console.log(result2)
            } catch (error) {
                console.log(error)
            }
        }
        load()
    

異步解決方案比較

  • callback

  • jquery的deferred

  • generator

  • Promise

  • async/await

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • JS中的單線程指的是在同一個時間內只能做一件事情。 好處:避免DOM渲染的沖突。瀏覽器根據HTML文件初始化需要渲...
    當壚小筑閱讀 505評論 0 0
  • 原文連接:https://blog.csdn.net/sinat_17775997/article/details...
    小豆soybean閱讀 4,365評論 0 7
  • 為什么會出現(xiàn)異步 js是一門為瀏覽器而誕生的語言,發(fā)展到現(xiàn)在,js已經不僅僅只在瀏覽器上運行了,服務端也可以運行j...
    lzksdxh閱讀 4,632評論 0 2
  • # Ajax標簽(空格分隔): 筆記整理---[TOC]### 從輸入網址開始:- 在學習ajax之前,你應該先了...
    V8閱讀 343評論 1 0
  • 弄懂js異步 講異步之前,我們必須掌握一個基礎知識-event-loop。 我們知道JavaScript的一大特點...
    DCbryant閱讀 2,879評論 0 5

友情鏈接更多精彩內容