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

javascript 使用sleep函數的常見方法詳解

 更新時間:2020年04月26日 09:17:47   作者:李小強  
這篇文章主要介紹了javascript 使用sleep函數的常見方法,結合實例形式分析總結了javascript sleep函數的功能、常見使用方法與操作注意事項,需要的朋友可以參考下

本文實例講述了javascript 使用sleep函數的常見方法。分享給大家供大家參考,具體如下:

一.什么是sleep函數?

花一點時間來聊一下sleep函數,首先什么是sleep函數?

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

例如:

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

控制臺輸出數字1后會間隔5秒后輸出數字2

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

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

二.為什么使用sleep?

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

因為setTimeout是通過回調函數來實現定時任務的,所以在多任務的場景下就會出現回調嵌套:

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

上面的方式存在回調嵌套的問題,我們希望有一個優(yōu)雅的方式來實現上面的例子:

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

三.實現sleep

接下來我們就分別用幾種不同的方法來實現下sleep方法

1.基于Date實現

通過死循環(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無暇處理其他任務。

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

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

2.基于Promise的sleep

為了解決ajax的回調嵌套問題,在jQuery1.8之后支持了Promise。但是單純的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函數來改寫上面的例子

3.基于Generator函數的sleep

我們對sleep的執(zhí)行使用Generator函數來執(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

可以看到整體的代碼看起來不存在嵌套的關系,還是比較舒服的。

并且執(zhí)行過程不會發(fā)生假死情況,不會阻塞其他任務的執(zhí)行。

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

當然這不是最終版,因為ES7為我們帶來了新的解決方案。

4.基于async函數的sleep

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

前面介紹了幾種比較簡單的sleep實現,接下來看一個比較難的實現。

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

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對象的execFileSync或者spawnSync創(chuàng)建一個同步進程,

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

6.使用npm sleep包

前面的內容都是我們自己實現的,其實npm上已經有很多相關的js包了。

我們來看看他們是怎么實現的,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

很強有沒有,sleep包是C++編寫,然后擴展到Node來實現sleep函數
也是一個不錯的選擇。

以上就是sleep的六種簡單實現。歡迎大家指出問題,我們一起進步。

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關于JavaScript相關內容可查看本站專題:《JavaScript常用函數技巧匯總》、《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》及《JavaScript數學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

相關文章

  • 微信小程序獲取手機系統信息的方法【附源碼下載】

    微信小程序獲取手機系統信息的方法【附源碼下載】

    這篇文章主要介紹了微信小程序獲取手機系統信息的方法,涉及微信小程序wx.getSystemInfo函數的簡單使用技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下
    2017-12-12
  • 判斷顏色是否合法的正則表達式(詳解)

    判斷顏色是否合法的正則表達式(詳解)

    下面小編就為大家?guī)硪黄袛囝伾欠窈戏ǖ恼齽t表達式(詳解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 簡單了解Javscript中兄弟ifream的方法調用

    簡單了解Javscript中兄弟ifream的方法調用

    這篇文章主要介紹了簡單了解Javscript中兄弟ifream的方法調用文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,,需要的朋友可以參考下
    2019-06-06
  • 用javascript實現頁內搜索的腳本代碼

    用javascript實現頁內搜索的腳本代碼

    用javascript實現頁內搜索的腳本代碼...
    2007-08-08
  • JS實現玩轉風車

    JS實現玩轉風車

    這篇文章主要為大家詳細介紹了JS實現玩轉風車,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 淺談js繼承的實現及公有、私有、靜態(tài)方法的書寫

    淺談js繼承的實現及公有、私有、靜態(tài)方法的書寫

    下面小編就為大家?guī)硪黄獪\談js繼承的實現及公有、私有、靜態(tài)方法的書寫。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • js 阻止子元素響應父元素的onmouseout事件具體實現

    js 阻止子元素響應父元素的onmouseout事件具體實現

    本文為大家介紹下js阻止子元素響應父元素的onmouseout事件,具體實現如下,感興趣的朋友可以參考下
    2013-12-12
  • MATLAB中fillmissing函數用法小結

    MATLAB中fillmissing函數用法小結

    這篇文章主要介紹了MATLAB中fillmissing函數用法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • uniapp實現微信H5掃碼功能的完整步驟

    uniapp實現微信H5掃碼功能的完整步驟

    在uni-app官網上發(fā)現uni-app不支持H5掃碼功能,但是下面的提示說明可以通過微信的JS-SDK實現掃碼功能,下面這篇文章主要給大家介紹了關于uniapp實現微信H5掃碼功能的完整步驟,需要的朋友可以參考下
    2022-11-11
  • 原生JS實現$.param() 函數的方法

    原生JS實現$.param() 函數的方法

    這篇文章主要介紹了原生JS實現$.param() 函數的方法,由于遇到相關序列化的問題,但是vue項目中由于減少隊jquery引用的限制,導致不能用$.param來序列化參數,下面小編給大家分享了實例代碼,需要的朋友參考下吧
    2018-08-08

最新評論