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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【JavaScript】【5】定时器(包含回调函数与Promise)

發布時間:2024/1/1 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【JavaScript】【5】定时器(包含回调函数与Promise) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、回調函數
  • 二、 Promise
    • promise對象
    • Promise對象的生成
    • 加載圖片寫成一個Promise
  • 三、定時器與清除定時器的方法
  • 四、京東購物車倒計時案例
  • 五、發送驗證碼案例
    • 在這里插入圖片描述
  • 總結


前言

什么是定時器
JavaScript提供定時執行代碼的功能,叫做定時器(timer),主要由setTimeout()和setInterval()這兩個函數來完成。它們向任務隊列添加定時任務。


了解回調函數和Promise對象

一、回調函數

  • 你不知道用戶何時單擊按鈕。 因此,為點擊事件定義了一個事件處理程序。 該事件處理程序會接受一個函數,該函數會在該事件被觸發時被調用。
  • 回調是一個簡單的函數,會作為值被傳給另一個函數,并且僅在事件發生時才被執行。 之所以這樣做,是因為 JavaScript 具有頂級的函數,這些函數可以被分配給變量并傳給其他函數(稱為高階函數)。通常會將所有的客戶端代碼封裝在 window 對象的 load 事件監聽器中,其僅在頁面準備就緒時才會運行
window.addEventListener('load', () => {//window 已被加載。//做需要做的。 })
  • 回調無處不在,不僅在 DOM 事件中。一個常見的示例是使用定時器:
setTimeout(() => {// 2 秒之后運行。 }, 2000)
  • XHR 請求也接受回調,在此示例中,會將一個函數分配給一個屬性,該屬性會在發生特定事件(在該示例中,是請求狀態的改變)時被調用:
const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => {if (xhr.readyState === 4) {xhr.status === 200 ? console.log(xhr.responseText) : console.error('出錯')} } xhr.open('GET', 'http://nodejs.cn') xhr.send()
  • 回調適用于簡單的場景!但是,每個回調都可以添加嵌套的層級,并且當有很多回調時,代碼就會很快變得非常復雜
window.addEventListener('load', () => {document.getElementById('button').addEventListener('click', () => {setTimeout(() => {items.forEach(item => {//你的代碼在這里。})}, 2000)}) })

這是一個簡單的四級嵌套,但是當嵌套越來越復雜時,不推薦使用多級嵌套。從 ES6 開始,JavaScript 引入了一些特性,可以幫助處理異步代碼而不涉及使用回調:Promise(ES6)和 Async/Await(ES2017)。

二、 Promise

promise對象

Promise對象是CommonJS工作組提出的一種規范,目的是為異步操作提供統一接口。

首先,它是一個對象,也就是說與其他JavaScript對象的用法,沒有什么兩樣;其次,它起到代理作用(proxy),充當異步操作與回調函數之間的中介。它使得異步操作具備同步操作的接口,使得程序具備正常的同步運行的流程,回調函數不必再一層層嵌套。
簡單說,它的思想是,每一個異步任務立刻返回一個Promise對象,由于是立刻返回,所以可以采用同步操作的流程。這個Promises對象有一個then方法,允許指定回調函數,在異步任務完成后調用。

  • 異步操作f1返回一個Promise對象,它的回調函數f2寫法如下
(new Promise(f1)).then(f2)
  • 多層回調函數
//傳統寫法 step1(function(value1){step2(value1,function(value2){step3(value2,function(value3){step4(value3,function(value4){...})})}) }) //Promise寫法 (new Promise(step1)).then(step2);.then(step3);.then(step4);

總的來說,傳統的回調函數寫法使得代碼混成一團,變得橫向發展而不是向下發展。Promises規范就是為了解決這個問題而提出的,目標是使用正常的程序流程(同步),來處理異步操作。它先返回一個Promise對象,后面的操作以同步的方式,寄存在這個對象上面。等到異步操作有了結果,再執行前期寄放在它上面的其他操作。

  • Promise對象的三種狀態:
    異步操作“未完成”(pending)
    異步操作“已完成”(resolved,又稱fulfilled)
    異步操作“失敗”(rejected)
    三種途徑的變換方式只有兩種:從未完成到已完成和從未完成到失敗
  • 變換方式只能發生一次,一旦狀態變為"已完成"或"失敗",就意味著不會發生新的狀態變化了。Promise對象的最終狀態只有兩種
    異步操作成功:Promise對象傳回一個值,狀態變為resolved
    異步操作失敗,Promise對象拋出一個錯誤,狀態變為rejected
// po是一個Promise對象 //Promise對象po使用then方法綁定兩個回調函數,操作成功返回console.log,操作失敗返回console.error,這兩個函數都接受異步操作傳回的值作為參數 po.then(console.log,console.error );
  • then方法可以鏈式使用
po.then(step1).then(step2).then(step3).then{console.log;console.error; //Promise對象的錯誤有傳遞性}

從同步角度看等價于

try {var v1 = step1(po);var v2 = step2(v1);var v3 = step3(v2);console.log(v3); } catch (error) {console.error(error); }

Promise對象的生成

var promise = new Promise(function(resolve,reject){if(/*異步操作成功*/){resolve(value); //在異步操作成功時調用,并將異步操作的結果,作為參數傳遞出去 }else{reject(error); //在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去 } })

可以使用then方法

po.then(function(value){//success },function(value){//failure });

加載圖片寫成一個Promise

var preloadImage = function(path){return new Promise(function(resolve,reject){var image = new Image();image.onload = resolve;image.onerror = reject;image.src = path;}) }

三、定時器與清除定時器的方法

1 推遲執行的代碼必須以字符串的形式,放入setTimerout
因為引擎內部使用eval函數,將字符串轉化為代碼。

setTimeout('console.log(1)',1000)

2 如果推遲執行的是函數,則可以直接將函數名,放入setTimeout。
一方面eval函數有安全顧慮,另一方面為了便于JavaScript引擎優化代碼,setTimeout方法一般總是采用函數名的形式

function fn(){ console.log(2); } setTimeout(fn,1000); //或者 setTimeout(function(){console.log(2); },1000)

3 清除定時器

function fn(){console(2); } var timer = setTimeout(fn,1000); clearTimeout(timer);

四、京東購物車倒計時案例

布局省略代碼如下(示例):

var day = document.querySelector('.day') var hour = document.querySelector(".hour"); var minute = document.querySelector('.minute'); var second = document.querySelector(".second"); var inputTime = +new Date('2022-6-4 22:00:00') countDown(); var timer = null; timer = setInterval(countDown,1000);var button2 = document.querySelector('.start'); button2.addEventListener('click',()=>{timer = setInterval(countDown,1000)})var button = document.querySelector('.stop'); button.addEventListener('click',function(){clearTimeout(timer); })function countDown(){var nowTime = +new Date(); //返回當前毫秒數var time = (inputTime - nowTime) / 1000; //時間差var d = parseInt(time / 60 / 60 /24);d = d < 10 ? '0'+d : d;day.innerHTML = d;var h = parseInt(time / 60 / 60 %24);h = h < 10? '0'+h : h;hour.innerHTML = h;var m = parseInt(time / 60 % 60);m = m < 10? '0'+m : m;minute.innerHTML = m;var s = parseInt(time % 60)s = s <10? '0'+s : s;second.innerHTML = s;}

五、發送驗證碼案例

布局省略代碼如下(示例):

//1 按鈕點擊后,禁用按鈕//2 同時按鈕里面的內容會變化,主要button里面的內容通過innerHTML修改//3 秒數定義一個變量在定時器里不斷遞減//4 如果變量為0說明時間到了,停止計數器,并復原按鈕初始狀態var button = document.querySelector('button');var time = 10;button.addEventListener('click',function(){button.disabled = true;var timer = setInterval(()=>{if(time == 0){//清除定時器和復原按鈕clearInterval(timer);button.disabled = false;button.innerHTML = '發送'; time = 10;}else{button.innerHTML = '還剩'+time+'秒發送';--time;}},1000)})// while(time == 0){// button.disabled = false;// button.innerHTML = '發送驗證碼';// }盡量不去使用while

總結

提示:這里對文章進行總結:
Promise對象還需要繼續學習。定時器要學會計數和清除

總結

以上是生活随笔為你收集整理的【JavaScript】【5】定时器(包含回调函数与Promise)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。