日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

JavaScript怎么模擬 delay、sleep、pause、wait 方法

來源: 責編: 時間:2023-09-22 20:12:28 324觀看
導讀許多編程語言都有一個 sleep 函數,可以延遲程序的執行若干秒。JavaScript缺少這個內置功能,但不用擔心。在這篇文章中,我們將探討在JavaScript代碼中實現延遲的各種技巧,同時考慮到該語言的異步性質。如何在 JS 中創建 sl

許多編程語言都有一個 sleep 函數,可以延遲程序的執行若干秒。JavaScript缺少這個內置功能,但不用擔心。在這篇文章中,我們將探討在JavaScript代碼中實現延遲的各種技巧,同時考慮到該語言的異步性質。Jic28資訊網——每日最新資訊28at.com

如何在 JS 中創建 sleep 函數

對于那些只想快速解決問題而不想深入了解技術細節的人,我們也有簡單明了的解決方案。下面是如何在你的JavaScript工具箱中添加一個 sleep 函數的最直接方式:Jic28資訊網——每日最新資訊28at.com

function sleep(ms) {  return new Promise(resolve => setTimeout(resolve, ms));}console.log('Hello');sleep(2000).then(() => { console.log('World!'); });

運行這段代碼,你會在控制臺看到 “Hello”。然后,在短暫的兩秒鐘后,“World!”v會接著出現。這是一種既簡潔又有效的引入延遲的方法。Jic28資訊網——每日最新資訊28at.com

如果你只是為了這個來的,那太好了!但如果你對“為什么”和“怎么做”的原因感到好奇,還有更多可以學習的內容。JavaScript中處理時間有其細微之處,了解這些可能會對你有所幫助。Jic28資訊網——每日最新資訊28at.com

理解JavaScript的執行模型

現在我們已經有了一個快速的解決方案,讓我們深入了解JavaScript的執行模型的機制。理解這一點對于有效地管理代碼中的時間和異步操作至關重要。Jic28資訊網——每日最新資訊28at.com

考慮以下Ruby代碼:Jic28資訊網——每日最新資訊28at.com

require 'net/http'require 'json'url = 'https://api.github.com/users/jameshibbard'uri = URI(url)response = JSON.parse(Net::HTTP.get(uri))puts response['public_repos']puts 'Hello!'

正如人們所期望的,這段代碼向GitHub API發送一個請求以獲取我的用戶數據。然后解析響應,輸出與我的GitHub帳戶關聯的公共倉庫的數量,最后在屏幕上打印“Hello!”。執行是從上到下進行的。Jic28資訊網——每日最新資訊28at.com

相比之下,這是相同功能的JavaScript版本:Jic28資訊網——每日最新資訊28at.com

fetch('https://api.github.com/users/jameshibbard')  .then(res => res.json())  .then(json => console.log(json.public_repos));console.log('Hello!');

如果你運行這段代碼,它會先在屏幕上輸出“Hello!”,然后輸出與我的GitHub帳戶關聯的公共倉庫的數量。Jic28資訊網——每日最新資訊28at.com

這是因為在JavaScript中,從API獲取數據是一個異步操作。JavaScript解釋器會遇到 fetch 命令并發送請求。然而,它不會等待請求完成。相反,它會繼續執行,將“Hello!”輸出到控制臺,然后當請求在幾百毫秒后返回時,它會輸出倉庫的數量。Jic28資訊網——每日最新資訊28at.com

如何在JavaScript中正確使用SetTimeout

既然我們已經更好地理解了JavaScript的執行模型,讓我們看看JavaScript是如何處理延遲和異步代碼的。Jic28資訊網——每日最新資訊28at.com

在JavaScript中創建延遲的標準方法是使用其 setTimeout 方法。例如:Jic28資訊網——每日最新資訊28at.com

console.log('Hello');setTimeout(() => {  console.log('World!'); }, 2000);

這將在控制臺上輸出 "Hello",然后兩秒后輸出 "World!"。在很多情況下,這已經足夠了:做某事,然后在短暫的延遲后,做其他事情。問題解決!Jic28資訊網——每日最新資訊28at.com

但不幸的是,事情并不總是那么簡單。Jic28資訊網——每日最新資訊28at.com

你可能會認為 setTimeout 會暫停整個程序,但事實并非如此。它是一個異步函數,這意味著其余的代碼不會等待它完成。Jic28資訊網——每日最新資訊28at.com

例如,假設你運行了以下代碼:Jic28資訊網——每日最新資訊28at.com

console.log('Hello');setTimeout(() => { console.log('World!'); }, 2000);console.log('Goodbye!');

你會看到以下輸出:Jic28資訊網——每日最新資訊28at.com

HelloGoodbye!World!

注意“Goodbye!”是如何出現在“World!”之前的?這是因為 setTimeout 不會阻塞其余代碼的執行。Jic28資訊網——每日最新資訊28at.com

這意味著你不能這樣做:Jic28資訊網——每日最新資訊28at.com

console.log('Hello');setTimeout(1000);console.log('World');

"Hello" 和 "World" 會立即被記錄在控制臺上,之間沒有明顯的延遲。Jic28資訊網——每日最新資訊28at.com

你也不能這樣做:Jic28資訊網——每日最新資訊28at.com

for (let i = 0; i < 5; i++) {  setTimeout(() => { console.log(i); }, i * 1000);}

花一秒鐘考慮一下上面的代碼片段可能會發生什么。Jic28資訊網——每日最新資訊28at.com

它不會在每個數字之間延遲一秒鐘打印數字 0 到 4。相反,你實際上會得到五個 4,它們在四秒后一次性全部打印出來。為什么呢?因為循環不會暫停執行。它不會等待 setTimeout 完成才進入下一次迭代。Jic28資訊網——每日最新資訊28at.com

那么 setTimeout 實際上有什么用呢?現在讓我們來看看。Jic28資訊網——每日最新資訊28at.com

setTimeout() 函數的檢查和最佳實踐

正如你可以在我們的 setTimeout 教程中閱讀到的,原生JavaScript setTimeout 函數在指定的延遲(以毫秒為單位)后調用一個函數或執行一個代碼片段。Jic28資訊網——每日最新資訊28at.com

這可能在某些情況下是有用的,例如,如果你希望在訪問者瀏覽你的頁面一段時間后顯示一個彈出窗口,或者你希望在從元素上移除懸停效果之前有短暫的延遲(以防用戶意外地鼠標移出)。Jic28資訊網——每日最新資訊28at.com

setTimeout 方法接受一個函數的引用作為第一個參數。Jic28資訊網——每日最新資訊28at.com

這可以是函數的名稱:Jic28資訊網——每日最新資訊28at.com

function greet(){  alert('Howdy!');}setTimeout(greet, 2000);

它可以是一個指向函數的變量(函數表達式):Jic28資訊網——每日最新資訊28at.com

const greet = function(){  alert('Howdy!');};setTimeout(greet, 2000);

或者它可以是一個匿名函數(在這種情況下是箭頭函數):Jic28資訊網——每日最新資訊28at.com

setTimeout(() => { alert('Howdy!'); }, 2000);

也可以將一段代碼字符串傳遞給 setTimeout 以供其執行:Jic28資訊網——每日最新資訊28at.com

然而,這種方法是不可取的,因為:Jic28資訊網——每日最新資訊28at.com

  1. 它很難閱讀(因此很難維護和/或調試)
  2. 它使用了一個隱含的 eval,這是一個潛在的安全風險
  3. 它比替代方案慢,因為它必須調用JS解釋器

如前所述,setTimeout 非常適合在延遲后觸發一次性操作,但也可以使用 setTimeout(或其表親 setInterval)來讓JavaScript等待直到滿足某個條件。例如,下面是如何使用 setTimeout 等待某個元素出現在網頁上的方式:Jic28資訊網——每日最新資訊28at.com

function pollDOM () {  const el = document.querySelector('my-element');  if (el.length) {    // Do something with el  } else {    setTimeout(pollDOM, 300); // try again in 300 milliseconds  }}pollDOM();

這假設該元素最終會出現。如果你不確定這是否會發生,你需要考慮取消計時器(使用 clearTimeout 或 clearInterval)。Jic28資訊網——每日最新資訊28at.com

在 JS 中使用遞增超時作為 Sleep 函數的替代方案

有時,你可能會發現自己想要在一系列操作中引入延遲。雖然你可以使用各種方法來模擬一個Sleep函數,但還有另一種經常被忽視的方法:遞增超時。Jic28資訊網——每日最新資訊28at.com

這個思路很簡單:你不是暫停整個執行線程,而是使用 setTimeout 為每個后續操作增加延遲。這樣,你可以創建一個延遲操作的序列,而不會阻塞瀏覽器或損害用戶體驗。Jic28資訊網——每日最新資訊28at.com

下面是一個快速示例:Jic28資訊網——每日最新資訊28at.com

let delay = 1000; // 從1秒的延遲開始for (let i = 0; i < 5; i++) {  setTimeout(() => {    console.log(`這是消息 ${i + 1}`);  }, delay);  delay += 1000; // 每次迭代延遲增加1秒}

在這個示例中,第一條消息將在1秒后出現,第二條消息在2秒后,依此類推,直到第五條消息在5秒后。Jic28資訊網——每日最新資訊28at.com

這種方法的優點是它不阻塞,易于實現,并且不需要了解 promises 或 async/await。然而,它不適用于需要精確計時或錯誤處理的復雜異步操作Jic28資訊網——每日最新資訊28at.com

現代JavaScript中的流控制

編寫 JavaScript 時,我們經常需要等待某件事情發生(例如,從 API 獲取數據),然后做出響應(例如,更新UI以顯示數據)。Jic28資訊網——每日最新資訊28at.com

上面的示例使用了一個匿名回調函數來實現這一目的,但如果你需要等待多個事情發生,語法很快就會變得相當復雜,你最終會陷入回調地獄。Jic28資訊網——每日最新資訊28at.com

幸運的是,這門語言在過去幾年里有了很大的發展,現在為我們提供了新的構造來避免這一點。Jic28資訊網——每日最新資訊28at.com

例如,使用 async await,我們可以重寫最初獲取 GitHub API信息的代碼:Jic28資訊網——每日最新資訊28at.com

(async () => {  const res = await fetch(`https://api.github.com/users/jameshibbard`);  const json = await res.json();  console.log(json.public_repos);  console.log('Hello!');})();

現在,代碼從上到下執行。JavaScript 解釋器等待網絡請求完成,首先記錄公共倉庫的數量,然后記錄“Hello!”消息。Jic28資訊網——每日最新資訊28at.com

將Sleep函數引入原生JavaScript

如果你還在看這篇文章,那么我猜你一定是想阻塞那個執行線程,并讓JavaScript等待一下。Jic28資訊網——每日最新資訊28at.com

下面是你可能會這樣做的方式:Jic28資訊網——每日最新資訊28at.com

function sleep(milliseconds) {  const date = Date.now();  let currentDate = null;  do {    currentDate = Date.now();  } while (currentDate - date < milliseconds);}console.log('Hello');sleep(2000);console.log('World!');

正如預期的那樣,這將在控制臺上打印“Hello”,暫停兩秒,然后打印“World!”Jic28資訊網——每日最新資訊28at.com

它通過使用Date.now方法獲取自1970年1月1日以來經過的毫秒數,并將該值分配給一個 date 變量。然后它創建一個空的 currentDate 變量,然后進入一個 do ... while 循環。在循環中,它會重復獲取自1970年1月1日以來經過的毫秒數,并將該值分配給之前聲明的 currentDate 變量。只要 date 和 currentDate 之間的差異小于所需的毫秒數的延遲,循環就會繼續進行。Jic28資訊網——每日最新資訊28at.com

任務完成了,對嗎?好吧,也不完全是……Jic28資訊網——每日最新資訊28at.com

如何在JavaScript中編寫更好的Sleep函數

也許這段代碼正是你所期望的,但請注意,它有一個很大的缺點:循環會阻塞JavaScript的執行線程,并確保在它完成之前沒有人能與你的程序進行交互。如果你需要很大的延遲,甚至有可能會讓整個程序崩潰。Jic28資訊網——每日最新資訊28at.com

那么應該怎么做呢?Jic28資訊網——每日最新資訊28at.com

事實上,也可以結合本文前面學到的技巧來制作一個不太侵入性的 sleep 方法:Jic28資訊網——每日最新資訊28at.com

function sleep(ms) {  return new Promise(resolve => setTimeout(resolve, ms));}console.log('Hello');sleep(2000).then(() => { console.log('World!'); });

這段代碼將在控制臺上打印“Hello”,等待兩秒,然后打印“World!”在底層,我們使用setTimeout 方法在給定的毫秒數后解析一個 promise。Jic28資訊網——每日最新資訊28at.com

注意,我們需要使用一個 then 回調來確保第二條消息是帶有延遲的。我們還可以在第一個回調函數后面鏈式地添加更多回調函數。Jic28資訊網——每日最新資訊28at.com

這樣做是可行的,但看起來不太好看。我們可以使用async ... await來美化它:Jic28資訊網——每日最新資訊28at.com

function sleep(ms) {  return new Promise(resolve => setTimeout(resolve, ms));}async function delayedGreeting() {  console.log('Hello');  await sleep(2000);  console.log('World!');  await sleep(2000);  console.log('Goodbye!');}delayedGreeting();

這看起來更好看,但這意味著使用 sleep 函數的任何代碼都需要被標記為 async。Jic28資訊網——每日最新資訊28at.com

當然,這兩種方法仍然有一個缺點(或特點),那就是它們不會暫停整個程序的執行。只有你的函數會睡眠:Jic28資訊網——每日最新資訊28at.com

function sleep(ms) {  return new Promise(resolve => setTimeout(resolve, ms));}async function delayedGreeting() {  console.log('Hello');  await sleep(2000); // await只暫停當前的異步函數  console.log('World!');}delayedGreeting();console.log('Goodbye!');

上面的代碼會依次打印出:Jic28資訊網——每日最新資訊28at.com

HelloGoodbye!World!

這樣,你可以根據需要靈活地使用不同的方法和技術來實現JavaScript中的延遲和異步操作。Jic28資訊網——每日最新資訊28at.com

創建 JS Sleep函數的最佳實踐

我們已經探討了各種在JavaScript中引入延遲的方法。現在讓我們總結一下哪種方法最適合不同的場景,以及哪種方法通常應該避免。Jic28資訊網——每日最新資訊28at.com

1.純粹的setTimeout

console.log('Hello');setTimeout(() => { console.log('World!'); }, 2000);

本文鏈接:http://www.www897cc.com/showinfo-26-11211-0.htmlJavaScript怎么模擬 delay、sleep、pause、wait 方法

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C++ 中的隱式轉換:機制、應用與警惕

下一篇: Spring常用注解@Import的三種使用方式,你都了解了嗎?

標簽:
  • 熱門焦點
  • vivo TWS Air開箱體驗:真輕 臻好聽

    在vivo S15系列新機的發布會上,vivo的最新款真無線藍牙耳機vivo TWS Air也一同發布,本次就這款耳機新品給大家帶來一個簡單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產
  • iPhone賣不動了!蘋果股價創年內最大日跌幅:市值一夜蒸發萬億元

    8月5日消息,今天凌晨美股三大指數高開低走集體收跌,道指跌0.41%;納指跌0.36%;標普500指數跌0.52%。熱門科技股也都變化極大,其中蘋果報181.99美元,跌4.8%,創
  • 0糖0卡0脂 旭日森林仙草烏龍茶優惠:15瓶到手29元

    旭日森林無糖仙草烏龍茶510ml*15瓶平時要賣為79.9元,今日下單領取50元優惠券,到手價為29.9元。產品規格:0糖0卡0脂,添加草本仙草汁,清涼爽口,富含茶多酚,保留
  • Rust中的高吞吐量流處理

    作者 | Noz編譯 | 王瑞平本篇文章主要介紹了Rust中流處理的概念、方法和優化。作者不僅介紹了流處理的基本概念以及Rust中常用的流處理庫,還使用這些庫實現了一個流處理程序
  • 一文看懂為蘋果Vision Pro開發應用程序

    譯者 | 布加迪審校 | 重樓蘋果的Vision Pro是一款混合現實(MR)頭戴設備。Vision Pro結合了虛擬現實(VR)和增強現實(AR)的沉浸感。其高分辨率顯示屏、先進的傳感器和強大的處理能力
  • 學習JavaScript的10個理由...

    作者 | Simplilearn編譯 | 王瑞平當你決心學習一門語言的時候,很難選擇到底應該學習哪一門,常用的語言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • OPPO、vivo、小米等國內廠商Q2在印度智能手機市場份額依舊高達55%

    7月20日消息,據外媒報道,研究機構的報告顯示,在全球智能手機出貨量同比仍在下滑的大背景下,印度這一有潛力的市場也未能幸免,出貨量同比也有下滑,多家廠
  • iQOO Neo8 Pro真機諜照曝光:天璣9200+和V1+旗艦雙芯加持

    去年10月,iQOO推出了iQOO Neo7系列機型,不僅搭載了天璣9000+,而且是同價位唯一一款天璣9000+直屏旗艦,一經上市便受到了用戶的廣泛關注。在時隔半年后,
  • 北京:科技教育體驗基地開始登記

      北京“科技館之城”科技教育體驗基地登記和認證工作日前啟動。首批北京科技教育體驗基地擬于2023年全國科普日期間掛牌,后續還將開展常態化登記。  北京科技教育體驗基
Top 主站蜘蛛池模板: 博兴县| 荥阳市| 琼中| 盐津县| 苏尼特右旗| 临漳县| 乐都县| 盐源县| 金乡县| 岳池县| 苗栗市| 广东省| 曲松县| 河曲县| 宝应县| 西峡县| 广东省| 汉川市| 若尔盖县| 远安县| 枝江市| 崇礼县| 富源县| 金门县| 太白县| 秭归县| 互助| 榕江县| 双辽市| 神木县| 孟州市| 马关县| 信阳市| 弥勒县| 盘锦市| 克什克腾旗| 东丽区| 凤台县| 上栗县| 虞城县| 乐平市|