日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ajax 同步_第3部分-0:同步和异步,还有回调需要了解一下

發(fā)布時間:2024/8/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ajax 同步_第3部分-0:同步和异步,还有回调需要了解一下 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

同步是什么
異步是什么
異步場景:
(1)定時任務(wù)
(2)網(wǎng)絡(luò)請求:Ajax 、圖片加載 全面分析前端的網(wǎng)絡(luò)請求方式
(3)事件綁定

異步產(chǎn)生知識點(diǎn):
進(jìn)程和線程
單線程 記一次 Vue 移動端活動倒計時優(yōu)化
JavaScript的執(zhí)行機(jī)制 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制
+ Event loop(定時任務(wù))最后一次搞懂 Event Loop
+ 宏任務(wù) 、微任務(wù) :【半月刊 3】前端高頻面試題及答案匯總
javascript的宏任務(wù)和微任務(wù)
解決異步:回調(diào)
回調(diào)產(chǎn)生的回調(diào)地域 —— Promise
手寫一個promise :手寫 Promise

(一)同步、異步 和回調(diào)

一、同步和異步是什么
同步:「 等待結(jié)果 」
異步:「 不等待結(jié)果 」直接進(jìn)行下一步 (不等但之后還想要拿到結(jié)果)
回調(diào): 回調(diào)是解決異步的常用方式,但回調(diào)不等于異步,回調(diào)也可以用在同步
注意幾點(diǎn)問題:

  • 這里我們所說的同步、異步,都屬于函數(shù)的范疇,也常常被稱之為同步函數(shù)(任務(wù))、異步函數(shù)(任務(wù))
  • 異步常使用回調(diào)的方式,但異步不是回調(diào)。
  • 回調(diào)既可以用來異步,也可以用來同步,也可以是異步。
// 同步的 sleepfunction sleep(seconds){var start = new Date()while(new Date() - start < seconds * 1000){}return } console.log(1) sleep(3) //3秒內(nèi)要不斷重復(fù)做一些無意義的工作才能保證js運(yùn)行按順序 console.log('wake up') console.log(2)//執(zhí)行結(jié)果的順序是:打印1——停3s——醒來——打印2,但事實(shí)上js環(huán)境內(nèi),停3s不可能不做事情

同步的 sleep//異步的 sleepfunction sleep(seconds, fn){setTimeout(fn, seconds * 1000) } console.log(1) sleep(3, ()=> console.log('wake up')) //回調(diào)函數(shù)操作異步 console.log(2)//先打印1,再打印2,最后3秒后,打印出'wake up',這樣時間可以大大減低

異步的 sleep

畫一張同步&異步工作的示意圖:

可以看出,用了異步之后,JS 的空閑時間多了許多。
但是注意,在 JS 空閑的這段時間,實(shí)際上是瀏覽器中的計時器在工作(很有可能是每過一段時間檢查是否時間到了,具體要看 Chrome 代碼)

(二)遇到異步實(shí)例和解決方法

一、異步實(shí)例
1、前端經(jīng)常遇到的異步
圖片加載是需要時間的

document.getElementsByTagNames('img')[0].width // 寬度為 0 console.log('done')

剛開始是直接獲取寬度

<!DOCTYPE html> <html> <head><meta charset="utf-8"><title>JS Bin</title> </head> <body><img src="http://imgsrc.baidu.com/image/c0%3Dshijue1%2C0%2C0%2C294%2C40/sign=8d22d2f93cd12f2eda08a62327abbf17/b8389b504fc2d56273fb63c3ed1190ef76c66c29.jpg" alt=""> </body> </html>var w = document.getElementsByTagNames('img')[0].width console.log(w)

先畫一個示意圖:

由此可知,js在img網(wǎng)絡(luò)請求還沒執(zhí)行完的時候緊隨執(zhí)行,可知為異步

//先獲取網(wǎng)絡(luò)請求前img信息,為空對象 var img = document.getElementsByTagName('img')[0]

img等待網(wǎng)絡(luò)請求完成后,獲取完整圖片信息后,便會觸發(fā)一個onload事件:

//等待完成之后執(zhí)行的內(nèi)容:img如果加載成功,就會觸發(fā)一個onload的事件,獲取它的寬度并打印出寬度 img.onload = function(){var w =img.widthconsole.log(w) }

?完整代碼:

var img = document.getElementsByTagName('img')[0]//異步不等繼續(xù)執(zhí)行,異步回調(diào)函數(shù):等待到網(wǎng)絡(luò)請求完成后觸發(fā)onload事件 img.onload = function(){var w =img.widthconsole.log(w) } console.log(img.width)//或者 document.getElementsByTagNames('img')[0].onload = function(){console.log(this.width) // 寬度不為 0console.log('real done') } console.log('done')

總結(jié):異步想拿到一個結(jié)果,常采用監(jiān)聽一個事件,然后告知(這個事件的完成時間不確定,不可預(yù)測),那就可以掛一個函數(shù)在onload上,等你請求完成,調(diào)用一下onload事件,此為回調(diào)函數(shù)。

2、面試題中的異步

let liList = document.querySelectorAll('li') for(var i=0; i<liList.length; i++){liList[i].onclick = function(){console.log(i)} }//獲取dom結(jié)構(gòu)的所有l(wèi)i元素,獲取li的長度去遍歷,每一個點(diǎn)擊后都能打印出東西

把 var i 改成 let 就可以破解:https://zhuanlan.zhihu.com/p/28140450

先讓我運(yùn)行上面的js代碼:

這里,js代碼運(yùn)行,還要注意一個技巧:變量提升,即

var i = 0//關(guān)鍵點(diǎn):變量提升為 var i i =0

那么,代碼如下:

let liList = document.querySelectorAll('li') var i //i是貫穿6次循環(huán)的一個變量(沒有多個) for(i=0; i<liList.length; i++){liList[i].onclick = function(){console.log(i)} }

畫一個時序圖:

可以看出,js執(zhí)行代碼時,當(dāng)i=5,i++結(jié)果為6的時候,并不小于liList.length,那么就跳出該循環(huán),最后輸出結(jié)果:i=6。js代碼執(zhí)行完,用戶開始操作他的鼠標(biāo),假設(shè)等待3ms后,執(zhí)行click li,當(dāng)你最先click的時候(i=0,liList[0],此時js已經(jīng)執(zhí)行完代碼,輸出i = 6 ),而不是在綁定事件的時候打印出幾,就是幾。

在這里,我們有必要知道,異步函數(shù)以下綁定事件為:

XXXX.onclick function(){console.log(i)}

瀏覽器并未等該異步執(zhí)行,直接進(jìn)入for循環(huán),直接將i=6輸出,然后第一個click才出現(xiàn),瀏覽器不會等click出現(xiàn)才去打印 i 值

如何解決?——使用let

假設(shè)你已經(jīng)知道let(不懂看這篇文章):

方應(yīng)杭:我用了兩個月的時間才理解 let?zhuanlan.zhihu.com

將代碼var i改為let:

let liList = document.querySelectorAll('li') for(let i=0; i<liList.length; i++){liList[i].onclick = function(){console.log(i)} }

運(yùn)行如下:

為何let能一一打印出結(jié)果呢?即let不會被提升到外面,let作用域即處于for循環(huán)函數(shù)里,即每一次循環(huán),liList[i]都有一個新的 i 值。let會在每一次進(jìn)入循環(huán)時,產(chǎn)生一個分身i1-i6.

畫一個運(yùn)行圖:【缺】

3、AJAX 中的異步(必須)

//同步的Ajax let request = $.ajax({url: '.', //1、獲取當(dāng)前 urlasync: false })//2、此時,該函數(shù)會等待請求完成才執(zhí)行下一步 console.log(request.responseText)//打印出這個請求的響應(yīng)文本,即當(dāng)前html頁面//responseText:響應(yīng)文本

相當(dāng)于同步,js在該函數(shù)中什么都沒做,但就是停了幾十ms,如同一個呆滯的人白白浪費(fèi)了一段空閑時間。

而Ajax的異步如何做?——async:true

$.ajax({url: '.',async: true,success: function(responseText){console.log(responseText)}//表示:如果請求返回回來,麻煩調(diào)用以下success這個函數(shù),然后把得出的結(jié)果打印出來 }) console.log('請求發(fā)送完畢')

在控制臺上,模擬一個網(wǎng)速很慢的操作:Network——slow 3G,如圖:

首先ajax函數(shù)會發(fā)一個請求,繼續(xù)執(zhí)行第二句console.log,這就是ajax中的異步。在這里,先不管ajax里的請求成功或失敗,直接執(zhí)行第二句代碼。不等,即為異步;而等則是一定要拿到結(jié)果才進(jìn)行下一步。時間不到,異步絕對拿不到結(jié)果。

畫一下圖:

如果我們把它改為同步:async:false,并模擬一個很慢的網(wǎng)速:Network——add,參數(shù)設(shè)置如下:

同步之后,代碼運(yùn)行演示如下:

二、異步的形式

從上面的例子中:可以通過綁定onload事件獲取寬度大小,或者ajax中的success函數(shù)

一般,有兩種方式拿到異步結(jié)果

1、傻逼方法:輪詢

2、正規(guī)方法:回調(diào)

回調(diào)的形式

  • Node.js 的 error-first 形式
fs.readFile('./1.txt', (error, content)=>{if(error){// 失敗}else{// 成功}})
  • jQuery 的 success / error 形式
$.ajax({url:'/xxx',success:()=>{},error: ()=>{}})
  • jQuery 的 done / fail / always 形式
$.ajax({url:'/xxx',}).done( ()=>{} ).fail( ()=>{} ).always( ()=> {})
  • Prosmise 的 then 形式
$.ajax({url:'/xxx',}).then( ()=>{}, ()=>{} ).then( ()=>{})

三、如何處理異常?

  • 如何使用多個 success 函數(shù)?
  • 在有多個成功回調(diào)的情況下,如何處理異常?
  • 自己返回 Promise

    function ajax(){return new Promise((resolve, reject)=>{做事如果成功就調(diào)用 resolve如果失敗就調(diào)用 reject}) }var promise = ajax() promise.then(successFn, errorFn)

    Promise 深入閱讀:http://www.cnblogs.com/hustskyking/p/promise.html Promise/A+ 規(guī)范:https://segmentfault.com/a/1190000002452115

    async / await

    function buyFruit(){return new Promise((resolve, reject)=>{做事如果成功就調(diào)用 resolve如果失敗就調(diào)用 reject}) } var promise = await ajax()async functon fn(){var result = await buyFruit()return result } var r = await fn() console.log(r)

    前言:

    在梳理知識點(diǎn)的時候,發(fā)現(xiàn)作為瀏覽器渲染中的機(jī)制之一——異步加載機(jī)制,當(dāng)用戶訪問站點(diǎn),需要下載各種資源,例如JS腳本,CSS,圖片,iframe等,它是實(shí)現(xiàn)現(xiàn)代網(wǎng)站進(jìn)行加載頁面時一種必不可少的手段。查資料加上老師拓展課程均對于異步加載機(jī)制還有很多方法可以說,故抽出來單獨(dú)進(jìn)行一個知識點(diǎn)的梳理。

    async和defer / setTimeout / 綁定事件 /Ajax // 回調(diào)函數(shù)//函數(shù)節(jié)流

    了解js腳本異步加載前,我們有必要先了解一下瀏覽器在頁面樣式和js的作用下出現(xiàn)的兩種頁面常見場景:白屏和fouc(無樣式內(nèi)容閃爍)。

    (一)白屏vsFOUC 和CSS和JS的位置順序

    一、白屏vsFOUC

    1、即指影響瀏覽器頁面加載順序的兩種場景

    • 白屏:特指一種場景,打開頁面是一片白色,突然頁面出現(xiàn),樣式正確。那么一片白色的時間,則稱之為白屏。
    • FOUC (Flash of Unstyled Content) :無樣式內(nèi)容閃爍,網(wǎng)速情況差,打開頁面時仍有樣式,之后樣式時有時無,甚至一開始并無出現(xiàn)樣式,突然樣式恢復(fù)。(常出現(xiàn)在firefox瀏覽器)

    此類現(xiàn)象,在不同瀏覽器進(jìn)行的資源加載和頁面渲染時,所采用的不同的處理方式,并不是bug。

    2、寫一個server,驗(yàn)證白屏和fouc效果

    在樣式文件index.html中

    //index.html <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>fouc & 白屏</title><!--在下面模擬一個延時裝置--> <link rel="stylesheet" href="b.css?t=10"> //設(shè)置這個工具,當(dāng)請求該文件時,服務(wù)器會延遲請求10s再去加載這個資源,以此可以模擬一個網(wǎng)速特別慢的情況<link rel="stylesheet" href="a.css?t=3"> </head> <body><p>hello</p><p>饑人谷</p> <!-- <script src="A.js?t=5"></script> --><img src="https://jirengu.com/data/upload/2017/0118/17/587f39fba695a.png" alt=""><!-- <link rel="stylesheet" href="c.css?t=6"> --><!-- <script src="http://a.jrg.com:8080/B.js?t=4" ></script> <script src="http://b.jrg.com:8080/A.js?t=8" ></script> --></body> </html>

    (1)關(guān)于白屏,需要注意的是,瀏覽器對于樣式和js的處理,即CSS 和 JS 放置順序。推薦:將樣式放在 <head>里面,將JS放在<body>內(nèi)部下方。

    如上面代碼所示,html頁面里引入了兩個css:a.css和b.css。b.css引用了c.ss(@import "./c.css?t=5";)b.css中加入了一個10s的延時文件(<link rel="stylesheet" href="b.css?t=10">),加載這個10s的css樣式文件,瀏覽器是如何完成加載工作,有兩種方式:

    第1種:html解析完成,此時10s延時的css文件先不管,先展示<body>里所展示的內(nèi)容,等css文件全加載后再去計算樣式,再去重新渲染一次

    第2種:即使html的dom樹已經(jīng)解析、渲染都完成,對未加載完成的樣式都必須等待,即css樣式要全部加載、獲取,img資源加載完成,此時底部JS立刻執(zhí)行,才一次性展示出頁面。例子中展示這種方法,即為白屏很久的原因。

    (2)不同瀏覽器的不同處理機(jī)制所出現(xiàn)的場景不同

    A、白屏場景(常出現(xiàn)在chrome):打開一個國外網(wǎng)站,使用國外服務(wù)器,嵌在css的字體使用的是谷歌字體,運(yùn)行特別慢,等了好久突然出現(xiàn)頁面樣式效果。這是因?yàn)轫撁嫘枰却齝ss樣式加載所有完成,甚至出現(xiàn)404加載失敗,最后才展示出頁面。那么那段加載時間,等待了幾秒左右的白色一片的頁面,就是白屏

    B、Fouc場景(常出現(xiàn)在Firefox):一開始的時候,先讓你看見樣式,如字的小號樣式,樣式加載完后看到所規(guī)定字號的大字。對用戶來說,同樣的樣式,突然從小變大,則這個場景就是Fouc(無樣式內(nèi)容閃爍)。

    二、CSS和JS的位置順序

    總結(jié):不管是css樣式,還是js文件,只要加長延時,都會造成白屏

    1、CSS 和 JS 最佳放置順序

    • 使用 link 標(biāo)簽將樣式表放在頂部
    • 將JS放在底部

    2、場景:假設(shè)JS文件頁面頂部:

    • JS腳本會阻塞后面內(nèi)容的呈現(xiàn)
    • JS腳本會阻塞其后組件(如圖片)的下載
    • JS加載時間過長,css需等待,則會出現(xiàn)一段時間白屏

    場景說明:引入一個JS文件在頂部,設(shè)置一個延時時間。

    加載順序:css—js—img—全部獲取到展現(xiàn)頁面效果

    此時,img和css加載時會并發(fā)加載,即如一個域名下同時加載兩個文件(并發(fā)是有限度的),加載在頂部的js時,會禁用并發(fā)img和css,并阻止其他內(nèi)容下載和渲染。

    js并不影響css加載,但是會影響css樣式的一個計算。當(dāng)js加載時,css已經(jīng)獲取到(不過此時頁面還是一片空白),直到j(luò)s獲取立即執(zhí)行后,圖片立刻出現(xiàn),頁面才展示效果。所以js文件放入頁面頂部<head>里,也會導(dǎo)致白屏現(xiàn)象出現(xiàn)

    3、JS加載特點(diǎn)總結(jié)

    (1)優(yōu)先加載js文件,加載后js立刻去執(zhí)行,展示頁面(CSS樣式則是全部加載完,然后一次性展示出頁面)

    注:css放前面,優(yōu)先加載;若放后面,其他資源則會阻礙css加載,那么時機(jī)就太晚。

    (2)由于渲染線程和js腳本線程是互斥的,白屏是渲染進(jìn)程被阻塞的原因,當(dāng)碰到script標(biāo)簽的時候,會先執(zhí)行js腳本,然后再渲染。

    (放頂部時)JS加載時機(jī)過晚導(dǎo)致一系列問題,腳本會阻塞后面內(nèi)容的呈現(xiàn)、腳本會阻塞其后組件的下載(主要指img資源下載)、白屏等。而(放底部)則可以先讓其他先加載完成,JS立刻執(zhí)行的特點(diǎn)可以“掃尾”最后的頁面效果

    (3)JS腳本操作頁面上的html+css元素,(放頂部時)JS先執(zhí)行,元素都未加載到(即不存在),未出現(xiàn)在文檔流中【加載,這里指資源加載和資源是否出現(xiàn)在文檔流中】,所以也不能操作相應(yīng)JS功能,此時后臺將會報錯。

    (4)(放頂部時)其他JS若作為一種框架語言,則能提前形成一個初步的框架有效構(gòu)成頁面結(jié)構(gòu)。

    三、解決方法:JS腳本的異步加載

    1、一個問題?

    即一個放在<head>的js文件,如下:

    <script src="script.js"></script>

    原本放在頂部的這個js文件,會提前加載,如何使它在頂部仍然稍后加載呢?

    2、解決方法: async和defer

    (1)作用:

    沒有 defer 或 async,瀏覽器會立即加載并執(zhí)行指定的腳本,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行。也就是說,使用defer 或 async后能夠改變這種加載、執(zhí)行的時機(jī)。

    常應(yīng)用在引用了廣告和統(tǒng)計的頁面中,不會影響、堵塞,更不會影響到到頁面其他元素

    (2) async HTML5里為script標(biāo)簽里新增了async屬性,用于異步加載腳本:不保證順序(獨(dú)立的個體)

    <script async src="script.js"></script> 或 <script type="text/javascript" src="alert.js" async="async"></script>

    瀏覽器解析到HTML里的該行script標(biāo)簽,發(fā)現(xiàn)指定為async,會異步下載解析執(zhí)行腳本(即加載后續(xù)文檔元素的過程將和 script.js 的加載并行進(jìn)行)。

    頁面的DOM結(jié)構(gòu)里假設(shè)<script>在img之前,如果你的瀏覽器支持async的話,就會異步加載腳本。此時DOM里已經(jīng)有img了,所以腳本里能順利取到img的src并彈框。 (3)defer script標(biāo)簽里可以設(shè)置defer,表示延遲加載腳本:

    腳本先不執(zhí)行,延遲到文檔解析和顯示后執(zhí)行,有順序

    <script defer src="script.js"></script> 或 <script type="text/javascript" src="alert.js" defer="defer"></script>

    瀏覽器解析到HTML里該行script標(biāo)簽,發(fā)現(xiàn)指定為defer,會暫緩下載解析執(zhí)行腳本,等到頁面文檔解析并加載執(zhí)行完畢后,才會加載該腳本(更精確地說,是在DOM樹構(gòu)建完成后,在DOMContentLoaded 事件觸發(fā)前,加載defer的腳本)。 頁面的DOM結(jié)構(gòu)里假設(shè)script在img圖片之前,如果你的瀏覽器支持defer的話,就會延遲到頁面加載完后才下載腳本。此時DOM里已經(jīng)有img元素了,所以腳本里能順利取到img的src并彈框。

    總結(jié):JS實(shí)質(zhì)采用一種可以更自由地選擇加載時機(jī)和任何位置,讓處于頂部的js文件能夠像在底部時,在頁面必要元素加載完成時進(jìn)行“異步”加載。

    總結(jié)

    以上是生活随笔為你收集整理的ajax 同步_第3部分-0:同步和异步,还有回调需要了解一下的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲三级在线 | 99re国产| 亚洲乱色熟女一区二区三区 | 绯色av一区二区 | 涩涩屋视频在线观看 | 日韩精品在线观看视频 | 欧美日韩国产二区 | 秋霞一级视频 | a免费视频 | 伊人伦理| 老熟女重囗味hdxx69 | 成年丰满熟妇午夜免费视频 | 亚洲三区精品 | 国产白丝一区二区三区 | 国产人妻大战黑人20p | 国产情侣小视频 | 草草影院最新网址 | 欧美a免费| 拔插拔插海外华人免费视频 | 蜜桃在线一区二区三区 | 久久福利片| 日韩精品中字 | 91免费看大片 | 天天免费视频 | 午夜视频久久 | 我色综合 | 亚洲乱码一区二区 | 欧美日韩乱| 老熟妇午夜毛片一区二区三区 | 国产正在播放 | 夜夜爽日日澡人人添 | a毛片毛片av永久免费 | 成人黄色免费在线观看 | 亚洲精品乱码久久久久久蜜桃动漫 | 亚洲欧洲无码一区二区三区 | 午夜精品福利一区二区蜜股av | aa成人 | 亚洲av无码专区在线电影 | 九九久久国产 | wwwsss在线观看 | 爱情岛论坛成人av | 99视频在线 | 国产在线国偷精品免费看 | 青草一区二区 | 色婷婷国产精品视频 | 亚洲自拍偷拍网站 | 欧美999| 免费成人蒂法网站 | 日日夜夜免费精品视频 | 黄色av一区二区 | 深夜网站在线观看 | 国产黄色网页 | 国产一区二区精品在线观看 | 天天射综合| 国产日韩欧美高清 | 丨国产丨调教丨91丨 | 成年人在线播放视频 | 懂色av一区二区三区在线播放 | 五月中文字幕 | 91亚洲精品久久久蜜桃网站 | 黄色大片免费看 | 无码精品在线视频 | 亚洲成人77777 | 中文久草 | 欧洲精品一区二区三区 | 性猛╳xxx乱大交 | 色人阁五月| 一区二区www| 激情超碰在线 | 91桃色在线| 日韩在线观看中文字幕 | 久久久区 | 亚洲国产精选 | 国产一区二区激情 | 国产欧美日韩三级 | jizzz18| 日本在线免费观看 | 岛国一区二区 | 欧美第二页| 国产精品无码一区二区三区 | 青青青在线视频观看 | 99久久99久久精品国产片桃花 | 婷婷资源网| 在线播放免费av | 天海翼中文字幕 | 天天色天| 国产福利一区二区 | 日本一区二区三区在线观看视频 | 天天看片中文字幕 | 狠狠干网址 | 美女88av| 二色av | 国产v亚洲 | 一级在线观看 | 日韩av在线网| 欧美理论片在线观看 | a天堂中文在线观看 | 国产资源在线免费观看 | 中文字幕一区在线播放 |