javascript如何使用sleep函數(shù)

小編這次要給大家分享的是javascript如何使用sleep函數(shù),文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

創(chuàng)新互聯(lián)公司專注于象山企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城系統(tǒng)網(wǎng)站開發(fā)。象山網(wǎng)站建設(shè)公司,為象山等地區(qū)提供建站服務(wù)。全流程按需搭建網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

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

花一點(diǎn)時(shí)間來聊一下sleep函數(shù),首先什么是sleep函數(shù)?

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

例如:

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

控制臺(tái)輸出數(shù)字1后會(huì)間隔5秒后輸出數(shù)字2

當(dāng)然上面的代碼是不能執(zhí)行的,因?yàn)閖s中是沒有sleep方法的。

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

二.為什么使用sleep?

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

因?yàn)閟etTimeout是通過回調(diào)函數(shù)來實(shí)現(xiàn)定時(shí)任務(wù)的,所以在多任務(wù)的場(chǎng)景下就會(huì)出現(xiàn)回調(diào)嵌套:

console.time('runTime:');
setTimeout(function(){
 console.log('1')
 setTimeout(function(){
 console.log('2');
 setTimeout(function(){
  console.log('3');
  console.timeEnd('runTime:');
 }, 2000);
 }, 3000);
}, 2000);
// 1
// 2
// 3
// runTime:: 7013.104ms

上面的方式存在回調(diào)嵌套的問題,我們希望有一個(gè)優(yōu)雅的方式來實(shí)現(xiàn)上面的例子:

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

三.實(shí)現(xiàn)sleep

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

1.基于Date實(shí)現(xiàn)

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

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

缺點(diǎn):

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

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

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

2.基于Promise的sleep

為了解決ajax的回調(diào)嵌套問題,在jQuery1.8之后支持了Promise。但是單純的Promise只是將之前的縱向嵌套改為了橫向嵌套,

最終結(jié)果是下面的代碼:

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

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

我們?cè)俅芜M(jìn)行優(yōu)化,使用ES6的Generator函數(shù)來改寫上面的例子

3.基于Generator函數(shù)的sleep

我們對(duì)sleep的執(zhí)行使用Generator函數(shù)來執(zhí)行,并且搭配co來進(jìn)行自執(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í)行過程不會(huì)發(fā)生假死情況,不會(huì)阻塞其他任務(wù)的執(zhí)行。

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

當(dāng)然這不是最終版,因?yàn)镋S7為我們帶來了新的解決方案。

4.基于async函數(shù)的sleep

ES7新增了async函數(shù),async函數(shù)最大的特點(diǎn)就是自帶執(zhí)行器,所以我們可以不借助co來實(shí)現(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

效果和之前的一樣。

5.使用child_process(子進(jìn)程)實(shí)現(xiàn)sleep函數(shù)

前面介紹了幾種比較簡(jiǎn)單的sleep實(shí)現(xiàn),接下來看一個(gè)比較難的實(shí)現(xiàn)。

原理是將sleep放在子進(jìn)程中執(zhí)行,不會(huì)影響其他進(jìn)程,看代碼:

var childProcess = require('child_process');
var nodeBin = process.argv[0];
 
function sleep(time) {
 childProcess.execFileSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']);
 // childProcess.spawnSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']);
}
 
console.time('runTime:');
console.log('1');
sleep(1000);
console.log('2');
sleep(2000);
console.log('3');
console.timeEnd('runTime:');
 
// 1
// 2
// 3
// runTime:: 3579.093ms

以上代碼,是通過childProcess對(duì)象的execFileSync或者spawnSync創(chuàng)建一個(gè)同步進(jìn)程,

在同步進(jìn)程中執(zhí)行定時(shí)器,定時(shí)器執(zhí)行完畢后回收進(jìn)程,程序繼續(xù)執(zhí)行。

6.使用npm sleep包

前面的內(nèi)容都是我們自己實(shí)現(xiàn)的,其實(shí)npm上已經(jīng)有很多相關(guān)的js包了。

我們來看看他們是怎么實(shí)現(xiàn)的,sleep

var sleep = require('sleep');
 
console.log('1');
console.time('runTime:');
sleep.sleep(2); //休眠2秒鐘
console.log('2');
sleep.msleep(1000); //休眠1000毫秒
console.log('3');
sleep.usleep(1000000) //休眠1000000微秒 = 1秒
console.log('4');
console.timeEnd('runTime:');
 
// 1
// 2
// 3
// 4
// runTime:: 4014.455ms

很強(qiáng)有沒有,sleep包是C++編寫,然后擴(kuò)展到Node來實(shí)現(xiàn)sleep函數(shù)
也是一個(gè)不錯(cuò)的選擇。

看完這篇關(guān)于javascript如何使用sleep函數(shù)的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。

網(wǎng)站名稱:javascript如何使用sleep函數(shù)
文章出自:http://bm7419.com/article10/gocjgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航品牌網(wǎng)站制作、動(dòng)態(tài)網(wǎng)站、軟件開發(fā)、虛擬主機(jī)、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)