Jquery ajax 同步阻塞引起的UI線程阻塞的坑(loading圖片顯示不出來 )

Jquery ajax 同步阻塞引起的UI線程阻塞的坑(loading圖片顯示不出來,layer.load延遲)jax重新獲取數據刷新頁面功能,因為ajax屬于耗時操作,想在獲取數據且加載頁面時顯示加載遮罩層,結果發現了ajax的好多坑。

Jquery ajax 同步阻塞引起的UI線程阻塞的坑(loading圖片顯示不出來,layer.load延遲)

ajax請示時,讓遮罩層顯示,ajax加載完畢后遮罩層消失。

因為我想讓loadChart()在賦值操作后執行,但如果async設為true時,往往會先執行loadChart(),之后才會賦值,

所以我只能將ajax設為同步。但同步后無論我怎么點按鈕,遮罩層都不會出來。?

這時:只有:async:true , loading mask層才會出來

?原因就是ajax的async設置為true時,ajax會委托瀏覽器另起一個線程,此線程與js線程和ui線程不沖突,只是在執行完成后再插入js事件環。

而ajax的async設置為false時并沒有啟動單獨的線程,還是在js主線程中執行,所以會與瀏覽器的渲染(UI)線程和js線程是互斥的,在執行js耗時操作時,頁面渲染會被阻塞掉。

當我們執行異步ajax的時候沒有問題,但當設置為同步請求時,其他的動作(ajax函數后面的代碼,還有渲染線程)都會停止下來。即使我的DOM操作語句是在發起請求的前一句,這個同步請求也會“迅速”將UI線程阻塞,不給它執行的時間。這就是代碼失效的原因。?

那么需要使用到:?deferred對象。

?總之,想讓ajax走完再加載頁面,就要使用同步。但是只要同步,ajax就會阻塞ui線程,使得loading顯示不出來。

只有使用了deffer對象和$.when(),既可以ajax設為異步,保證了loading的正常顯示,又可以保證在ajax走完再加載頁面。因為$.when().done()會在deffer.resolve()之前的代碼全部走完后才走done中的代碼。

我改成這樣。由于ajax為同步時點擊切換比較卡。能用異步最好還是用異步,用defferred對象后就可以把async換成true了。$.when()函數只接受defferred對象,所以我們在toGetData中需要先創建對象,再return就解決了。defer.resolve(ret)用于控制ajax何時結束,比如我執行完賦值操作結束ajax,進入.done()中的回調函數,它還可以把數據ret也帶出來使用,這里我沒有用到,這里執行完loadChart()操作后遮罩層消失。所以它能保證deffer.resolve之前的代碼執行完再執行回到函數,async設為true也沒任何影響。

?????這樣就完美解決了因為ajax阻塞線程導致loading層出不來的問題啦。

<script>
? ? var data;
? ? function toGetData() {
? ? ? ? var defer = $.Deferred();
? ? ? ? $.ajax({
? ? ? ? ? ? url: 'xxx',?
? ? ? ? ? ? type: "post", // 請求類型
? ? ? ? ? ? data: {
? ? ? ? ? ? },?
? ? ? ? ? ? dataType: 'json',?
? ? ? ? ? ? async: true, // 是否異步
? ? ? ? ? ? success: function (ret) {
? ? ? ? ? ? ? ? if (ret) {
? ? ? ? ? ? ? ? ? ? data=ret;
? ? ? ? ? ? ? ? ? ? defer.resolve(ret)
?
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? alert("無數據");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }?
? ? ? ? });
? ? ? ? return defer;
? ? }
? ? $('button').click(function(){
? ? ? ? $(".shadow").show()
? ? ? ? $.when(toGetData()).done(function(ret){
? ? ? ? ? ? loadChart()
? ? ? ? ? ? $(".shodow").hide() ? //所有的ajax的邏輯可以在這個地方進行處理
? ? ? ? });
? ? })
</script>

什么是deferred對象?

開發網站的過程中,我們經常遇到某些耗時很長的javascript操作。其中,既有異步的操作(比如ajax讀取服務器數據),也有同步的操作(比如遍歷一個大型數組),它們都不是立即能得到結果的。

通常的做法是,為它們指定回調函數(callback)。即事先規定,一旦它們運行結束,應該調用哪些函數。

但是,在回調函數方面,jQuery的功能非常弱。為了改變這一點,jQuery開發團隊就設計了deferred對象。

簡單說,deferred對象就是jQuery的回調函數解決方案。在英語中,defer的意思是"延遲",所以deferred對象的含義就是"延遲"到未來某個點再執行。

它解決了如何處理耗時操作的問題,對那些操作提供了更好的控制,以及統一的編程接口。它的主要功能,可以歸結為四點。下面我們通過示例代碼,一步步來學習。

?

 $.ajax({

    url: "test.html",

    success: function(){
      alert("哈哈,成功了!");
    },

    error:function(){
      alert("出錯啦!");
    }

  });

ajax操作的鏈式寫法?

?

 $.ajax("test.html")

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯啦!"); });

指定同一操作的多個回調函數?

?

 $.ajax("test.html")

  .done(function(){ alert("哈哈,成功了!");} )

  .fail(function(){ alert("出錯啦!"); } )

  .done(function(){ alert("第二個回調函數!");} );

?多個操作指定回調函數

?

$.when($.ajax("test1.html"), $.ajax("test2.html"))

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯啦!"); });

普通操作的回調函數接口?

var wait = function(){

    var tasks = function(){

      alert("執行完畢!");

    };

    setTimeout(tasks,5000);

  };

普通回調函數需要改造:

var dtd = $.Deferred(); // 新建一個deferred對象

  var wait = function(dtd){

    var tasks = function(){

      alert("執行完畢!");

      dtd.resolve();?// 改變deferred對象的執行狀態

    };

    setTimeout(tasks,5000);

    return dtd;

  };

?

$.when(wait())

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯啦!"); });

上面這種寫法,還是有問題。那就是dtd是一個全局對象,所以它的執行狀態可以從外部改變。

參考:

jQuery的deferred對象詳解 - 阮一峰的網絡日志?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Elasticsearch自動清理腳本

腳本 我在data下創建的腳本文件就叫:vi /data/clear_log.sh,內容如下 #!/bin/sh #獲取時間 time=`date +%Y-%m-%d %H:%M:%S` cipan=`df -h| grep sda3` #查詢磁盤使用率 liang=`df -h| grep sda3 |grep -v grep |awk {print $5}|tr -d

【數據結構】一題帶你出師鏈表!

&#x1f984;個人主頁:修修修也 &#x1f38f;所屬專欄:數據結構 ??操作環境:Visual Studio 2022 題目鏈接 138. 隨機鏈表的復制https://leetcode.cn/problems/copy-list-with-random-pointer/ 題目描述 給你一個長度為 n 的鏈表&#xff0c;每個節點包含一個額外增加的隨機…

Make a BESD file from QTLtools output

Make a BESD file from QTLtools output # 根據基因名與變異rsid編號去重 library(tidyverse) library(readxl) qtltoolsnomi <- read_table("qtltoolsnomi.txt",col_names F) qtltoolsnomi %>% distinct(X1,X8, .keep_all TRUE) -> qtltool qtltool …

qml ParticleSystem3D使用介紹

在 Qt Quick 3D 中,ParticleSystem3D 是用來創建和控制3D粒子系統的元素。粒子系統是圖形編程中用于模擬液體、煙霧、火、星空等現象的技術,它通過生成大量小粒子來模擬這些效果。ParticleSystem3D 提供了一個框架,允許開發者定義粒子的各種屬性,如生命周期、速度、顏色、大…

王道p149 9.設樹B是一棵采用鏈式結構存儲的二叉樹,編寫一個把樹 B中所有結點的左、右子樹進行交換的函數。(c語言代碼實現)

本題代碼如下 void swap(tree* t) {if (*t){treenode* temp (*t)->lchild;(*t)->lchild (*t)->rchild;(*t)->rchild temp;swap(&(*t)->lchild);swap(&(*t)->rchild);} } 完整測試代碼 #include<stdio.h> #include<stdlib.h> typed…

C#string.Format的一些使用

C#中的string.Format方法是一個用于格式化字符串的功能強大的方法。它允許您通過將占位符替換為實際的值來創建格式化的字符串。 一、基本語法是&#xff1a; string.Format(format, arg0, arg1, arg2, ...) 其中&#xff0c; format是一個字符串&#xff0c;其中包含要格式…

Java常用類

目錄 包裝類 裝箱和拆箱 包裝類型和String的轉換&#xff0c;包裝類的常用方法 包裝類 裝箱和拆箱 package com.edu.wrapper;public class Interger01 {//演示int<-->Integer的裝箱和拆箱//手動裝箱int n1100;Integer integer new Integer(n1);Integer integer01 In…

HCIP---MPLS---LDP

文章目錄 前言一、pandas是什么&#xff1f;二、使用步驟 1.引入庫2.讀入數據總結 前言 MPLS 基于標簽轉發表進行轉發&#xff0c;與路由表類似&#xff0c;標簽轉發表有兩種獲取渠道&#xff1a;一是手動配置(類似靜態路由)&#xff0c;二是通過協議自動學習(類似OSPF)。手動配…

6.1.webrc媒體協商

那今天呢&#xff1f;我們來看一下y8 rtc的媒體協商&#xff0c;那實際上在我們之前的課程中呢&#xff1f;我已經向你介紹過y8 rtc的媒體協商了。只不過呢&#xff0c;角度是不一樣的&#xff0c;在之前介紹外邊tc媒體協商的時候呢&#xff0c;我們是從應用的角度來看。那web …

ActiveMQ消息中間件應用場景

一、ActiveMQ簡介 ActiveMQ是Apache出品&#xff0c;最流行的&#xff0c;能力強勁的開源消息總線。ActiveMQ是一個完全支持JMS1.1和J2EE1.4規范的JMS Provide實現。盡管JMS規范出臺已經是很久的事情了&#xff0c;但是JMS在當今的J2EE應用中仍然扮演這特殊的地位。 二、Active…

《第一行代碼:Android》第三版-2.5.4數據類與單例_數據類

本文主要講述數據類&#xff0c;以前用java實現數據類很麻煩&#xff0c;寫很多代碼&#xff0c;就是搭個數據類的框架。kotlin用data class 關鍵字&#xff0c;給你簡化了數據類的創建&#xff0c;比較貼心。 就是自動為你創建了&#xff1a;equals()、hashCode()、toString(…

深入理解JVM 類加載機制

深入理解JVM 類加載機制 虛擬機如何加載Class文件&#xff1f; Class文件中的信息進入到虛擬機后會發生什么變化&#xff1f; 類加載機制就是Java虛擬機把描述類的數據從Class文件加載到內存&#xff0c;并對數據進行校驗、轉換解析和初始化&#xff0c;最終形成可以被虛擬機…

實現點擊一個選框 使得一個組件的可選性修改

實現效果 代碼 html <div class"divrow"><el-checkbox-group v-model"isSendTag" :max"1"><el-checkbox v-for"(item, index) in isSendTagOptions" :key"index" :label"item.value">{{item.…

【C++設計模式】單例模式singleton

C 設計模式–單例模式singleton 單例模式 單例模式是指確保一個類在任何情況下都絕對只有一個實例&#xff0c;并提供一個全局訪問點。 優點&#xff1a;內存中只有一個實例&#xff0c;減少內存開銷&#xff1b;避免對資源多重占用&#xff1b;設置全局訪問點&#xff0c;嚴…

【Axure教程】用中繼器制作卡片多條件搜索效果

卡片設計通過提供清晰的信息結構、可視化吸引力、易擴展性和強大的交互性&#xff0c;為用戶界面設計帶來了許多優勢&#xff0c;使得用戶能夠更輕松地瀏覽、理解和互動。 那今天就教大家如何用中繼器制作卡片的模板&#xff0c;以及完成多條件搜索的效果&#xff0c;我們會以…

并發與并行

并發和并行是操作系統中的兩個重要概念&#xff0c;它們在定義和處理任務的方式上有一些區別。 并發&#xff08;concurrency&#xff09;是指在一段時間內&#xff0c;有多個程序都處于啟動運行到運行完畢之間&#xff0c;但任一時刻點上只有一個程序在處理機上運行。它是一種…

Vue偵聽器

Vue偵聽器是根據組件狀態做DOM更新或者異步更新其他級聯狀態的。計算屬性的主要目標是根據已有數據計算出組件的狀態&#xff0c;它是組件內部的計算&#xff0c;計算結果在組件內部應用。偵聽器的主要目標是根據組件狀態的變動&#xff0c;做級聯的或者異步的操作或DOM更新&am…

STM32F103C8T6第6天:adc、iic、spi、溫濕度dht11在lcd1602顯示

1. ADC介紹 ADC是什么&#xff1f; Analog-to-Digital Converter&#xff0c;指模擬/數字轉換器 ADC的性能指標 量程&#xff1a;能測量的電壓范圍分辨率&#xff1a;ADC能辨別的最小模擬量&#xff0c;通常以輸出二進制數的位數表示&#xff0c;比如&#xff1a;8、10、1…

【Spring篇】Spring注解式開發

本文根據嗶哩嗶哩課程內容結合自己自學所得&#xff0c;用于自己復習&#xff0c;如有錯誤歡迎指正&#xff1b; 我在想用一句話激勵我自己努力學習&#xff0c;卻想不出來什么驚為天人、精妙絕倫的句子&#xff0c;腦子里全是上課老師想說卻沒想起的四個字 “ 唯手熟爾 ”&am…

自動駕駛術語匯總

目錄 智駕級別芯片相關自動駕駛相關輔助駕駛相關預警相關傳感器相關泊車相關安全相關車燈相關 智駕級別 L0-L2屬于輔助駕駛&#xff0c;L4-L5才算自動駕駛 L0&#xff08;Level 0&#xff09;&#xff1a;無自動化。這是大多數傳統汽車的級別&#xff0c;所有的駕駛任務都需要…