前端學(xué)習(xí)總結(jié)一: Js 異步進階

一、Promise

  1. 異步操作,解決 callback hell 問題

  2. 三種狀態(tài): pending, resolved, rejected
    狀態(tài)的表現(xiàn)和變化,pending ->resolved pending ->rejected,變化不可逆

  3. then 正常狀態(tài)返回 resolved ,有報錯則返回 rejected
    catch 正常狀態(tài)返回 resolved ,有報錯則返回 rejected

二、 async 和 await

  1. 同步語法,消滅異步回調(diào)函數(shù),async/await只是一個語法糖
    await 函數(shù)后面的都屬于回調(diào)

  2. async/await 與 promise 的關(guān)系

    • 執(zhí)行async 函數(shù),返回的是 promise 對象
    • await 相當(dāng)于 promise 的 then
    • try...catch 可以捕獲異常,代替了 promise 的 catch
async function fn(){
    return 100
}

(async function(){
    const a = fn    // 返回上面的函數(shù)
    const b = await fn()  // 返回 100
})()

三、event loop

image.png

借用雙越老師的一張圖具體講解,先來一個簡單版的:

  • 將第一行代碼 console.log('Hi') 放入Call Stack(調(diào)用棧)
  • 執(zhí)行,瀏覽器打印出 Hi
  • 清空 Call Stack
  • 將setTimeout 方法放入 Call Stack,執(zhí)行發(fā)現(xiàn)這個是個異步函數(shù),先推入 web API 清空 Call Stack
  • 將最后一行代碼 console.log('Bye') 推入 Call Stack ,執(zhí)行,打印出 Bye,清空 Call Stack
  • 此時所有同步代碼執(zhí)行完畢
  • Event Loop 開始啟動,輪詢查找 Callback Queue里是否有可執(zhí)行的語句
  • 時機到(定時,網(wǎng)絡(luò)請求,用戶操作等),將里面可以執(zhí)行的代碼推入 Callback Queue
  • Event Loop 查到有可執(zhí)行語句,將此語句推入 Call Stack ,執(zhí)行,打印出 cb1,清空 Call Stack
  • Event Loop 繼續(xù)輪詢查找(永動機)

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

宏任務(wù):setTimeout, setInterval, Ajax,DOM 事件
微任務(wù):promise,async/await

微任務(wù)比宏任務(wù)執(zhí)行時機要早

image.png

依然是雙越老師的圖,我們再講一次升級版的瀏覽器執(zhí)行方式:

  • 首先依然是按照代碼順序,將代碼推入 Call Stack
  • 同步代碼,執(zhí)行,清空 Call Stack
  • Call Stack 中發(fā)現(xiàn)代碼是 promise 或者 async/await 代碼,執(zhí)行,將回調(diào)代碼放入micro task queue
  • Call Stack 中發(fā)現(xiàn)代碼是 setTimeout 或者 DOM 操作等等,執(zhí)行,將回調(diào)代碼放入 web APIs
  • 此時同步代碼執(zhí)行完畢
  • Event Loop 開始啟動
  • 開始執(zhí)行微任務(wù),將 micro task queue 的代碼推入 callback queue,觸發(fā) Event Loop 將此代碼推入 Call Stack ,執(zhí)行,清空
  • 微任務(wù)執(zhí)行完畢
  • 嘗試 DOM 渲染
  • 執(zhí)行宏任務(wù),時機到時,將 Web APIs 里的代碼推入 callback queue,觸發(fā) Event Loop 將此代碼推入 Call Stack ,執(zhí)行,清空
  • Event Loop 繼續(xù)輪詢查找(永動機)
宏任務(wù)和微任務(wù)的區(qū)別
  • 宏任務(wù): DOM 渲染后觸發(fā),由 ES6 語法規(guī)定(執(zhí)行前推入micro task queue)
  • 微任務(wù): DOM 渲染前觸發(fā),由瀏覽器規(guī)定的(執(zhí)行前推入 Web APIs棧中)

四、for of

一個異步遍歷方法,話不多說,直接貼代碼

// for of
function muti(num) {
    const a = new Promise(resolve => {
        setTimeout(() => {
            resolve(num * num)
        }, 1000)
    })
    return a;
}

let arr = [2, 4, 6]
!(async function(){
    for(let i of arr) {
        const res = await muti(i)
        console.log(res)
    }
})()

手寫一個 ajax 方法

// 手寫一個 ajax 方法
function ajax(url){
    const p = new Promise((resolve,reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET',url,true)
        xhr.onreadystatechange = function () {
            if(xhr.readyState === 4) {
                if(xhr.status === 200) {
                    console.log(xhr);
                    resolve(JSON.parse(xhr.response))
                } else {
                    reject(new Error('404 not found'))
                }
            }
        }
        xhr.send(null)
    })
    
    return p
}

// 試一下
const url = 'http://demo.mall.10010.com:8104/scaffold-app/scaffold/queryPagealiasProData?page_alias=two-in-one'
ajax(url).then((res) => {
    console.log(res);
}).catch(err => console.log(err))


手寫深度比較

// 手寫深度比較 
function isObject(obj) {
    return typeof obj === 'object' && obj != null
}

function isEqual (obj1, obj2) {
    if(!isObject(obj1) || !isObject(obj2)) {
         return  obj1 === obj2
    }
    if (obj1 === obj2) {
        return true;
    }
    const obj1Key = Object.keys(obj1)
    const obj2Key = Object.keys(obj2)
    if (obj1Key.length != obj2Key.length) {
        return false
    }
    for(let key in obj1) {
        const res = isEqual(obj1[key], obj2[key])
        if(!res){
            return false
        }
    }
    return true
}

jsonp 原理(不是真正的 ajax)

幾個方面來解答:

  • 瀏覽器同源策略和跨域
  • 哪些 html 標(biāo)簽可以繞過跨域(Image script)
  • 利用 script 封裝成 jsonp
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容