欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實現(xiàn)sleep睡眠函數(shù)的幾種簡單方法總結(jié)

 更新時間:2023年01月05日 11:24:14   作者:謝向晚  
sleep是一種函數(shù),他的作用是使程序暫停指定的時間,起到延時的效果,下面這篇文章主要給大家介紹了關(guān)于JavaScript實現(xiàn)sleep睡眠函數(shù)的幾種簡單方法總結(jié),文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

一.什么是sleep函數(shù)?

sleep是一種函數(shù),他的作用是使程序暫停指定的時間,起到延時的效果。

官方介紹:sleep是一種函數(shù),作用是延時,程序暫停若干時間,在執(zhí)行時要拋出一個中斷異常,必須對其進行捕獲并處理才可以使用這個函數(shù)。

例如:

console.log('1');
sleep(2000);
console.log('2');

控制臺輸出數(shù)字1后 會間隔2秒后輸出數(shù)字2

當然上面的代碼是不能執(zhí)行的,因為js中是沒有sleep方法的。

所以這一篇文章主要介紹幾種在js中實現(xiàn)sleep的方式。

二.為什么使用sleep?

看到這里有人會問了,為什么要使用sleep,上面的例子我可以使用setTimeout來實現(xiàn)啊?

因為setTimeout是通過回調(diào)函數(shù)來實現(xiàn)定時任務(wù)的,所以在多任務(wù)的場景下就會出現(xiàn)回調(diào)嵌套:

console.time('runTime:');
  setTimeout(() => {
    console.log('1');
    setTimeout(() => {
      console.log('2')
      setTimeout(() => {
        console.log('3')
        console.timeEnd('runTime:');
      }, 2000);
    }, 3000);
  }, 2000);
//結(jié)果:
//1
//2
//3
//runTime:: 7017.87890625 ms

上面的方式存在回調(diào)嵌套的問題,我們希望可以利用sleep函數(shù)更方便優(yōu)雅地實現(xiàn)上面的例子。

三.實現(xiàn)sleep

接下來我們就分別用幾種不同的方法來實現(xiàn)下sleep方法:

基于Date實現(xiàn)

通過死循環(huán)來阻止代碼執(zhí)行,同時不停比對是否超時。

function sleep(time){
 var timeStamp = new Date().getTime();
 var endTime = timeStamp + time;
 while(true){
 if (new Date().getTime() > endTime){
  return;
 } 
 }
}
console.time('runTime:');
sleep(2000);
console.log('1');
sleep(3000);
console.log('2');
sleep(2000);
console.log('3');
console.timeEnd('runTime:');
// 1
// 2
// 3
// runTime:: 7004.301ms

缺點:

以上的代碼不會讓線程休眠,而是通過高負荷計算使cpu無暇處理其他任務(wù)。

這樣做的缺點是在sleep的過程中其他所有的任務(wù)都會被暫停,包括dom的渲染。

所以sleep的過程中程序會處于假死狀態(tài),并不會去執(zhí)行其他任務(wù)

基于Promise的sleep

單純的Promise只是將之前的縱向嵌套改為了橫向嵌套:

function sleep(time){
 return new Promise(function(resolve){
 setTimeout(resolve, time);
 });
}
console.time('runTime:');
console.log('1');
sleep(1000).then(function(){
 console.log('2');
 sleep(2000).then(function(){
 console.log('3');
 console.timeEnd('runTime:');
 });
});
console.log('a');
// 1
// a
// 2
// 3
// runTime:: 3013.476ms

這其實和之前的setTimeout嵌套沒什么區(qū)別,也很難看。

我們再次進行優(yōu)化,使用ES6的Generator函數(shù)來改寫上面的例子

基于Generator函數(shù)的sleep

我們對sleep的執(zhí)行使用Generator函數(shù)來執(zhí)行,并且搭配co來進行自執(zhí)行。

var co = require('co');
 
function sleep(time){
 return new Promise(function(resolve){
 setTimeout(resolve, time);
 });
}
 
var run = function* (){
 console.time('runTime:');
 console.log('1');
 yield sleep(2000);
 console.log('2');
 yield sleep(1000);
 console.log('3'); 
 console.timeEnd('runTime:');
}
 
co(run);
console.log('a');
// 1
// a
// 2
// 3
// runTime:: 3004.935ms

可以看到整體的代碼看起來不存在嵌套的關(guān)系,并且執(zhí)行過程不會發(fā)生假死情況,不會阻塞其他任務(wù)的執(zhí)行。

但是多了一個co執(zhí)行器的引用,所以還是有瑕疵。

基于async函數(shù)的sleep

async函數(shù)最大的特點就是自帶執(zhí)行器,所以我們可以不借助co來實現(xiàn)sleep了

function sleep(time){
 return new Promise((resolve) => setTimeout(resolve, time));
}
 
async function run(){
 console.time('runTime:');
 console.log('1');
 await sleep(2000);
 console.log('2');
 await sleep(1000);
 console.log('3'); 
 console.timeEnd('runTime:');
}
 
run();
console.log('a');
 
// 1
// a
// 2
// 3
// runTime:: 3009.984ms

附:還有一種死循環(huán)寫法(參考自網(wǎng)絡(luò))

思路是利用系統(tǒng)時間,一旦沒有運行到自己設(shè)定的時間就讓程序一直在循環(huán)里計算(個人感覺實現(xiàn)簡單,實際運行可能有點恐怖)

function sleep(numberMillis) { 
    //記錄當前時間
    var now = new Date(); 
    //設(shè)置未來的某個時間
    var exitTime = now.getTime() + numberMillis; 
    while (true) { 
        //獲取當前時間
        now = new Date(); 
        //檢查是否到了設(shè)置好的未來時間
        if (now.getTime() > exitTime) 
        return; 
    } 
}

總結(jié)

到此這篇關(guān)于JavaScript實現(xiàn)sleep睡眠函數(shù)的幾種簡單方法總結(jié)的文章就介紹到這了,更多相關(guān)JS實現(xiàn)sleep睡眠函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論