摘要:首先我們來講這個棧在中,每當有函數(shù)被執(zhí)行的時候都會在當前的執(zhí)行堆棧中創(chuàng)建一個新的堆棧幀,并放到棧頂。因為是鏈式調(diào)用,所以代碼一直在同一個作用于中執(zhí)行,也就是說當前的堆棧幀一直沒有被移出棧。
前言
前幾天在稀土上看到一篇面試的帖子,里面微信有一道題是lazyman的實現(xiàn),具體要做的事情就是
LazyMan(“Hank”) //Hi! This is Hank! LazyMan(“Hank”).sleep(10).eat(“dinner”) // Hi! This is Hank! // 等待10秒.. // Wake up after 10 // Eat dinner~ LazyMan(“Hank”).eat(“dinner”).eat(“supper”) // Hi This is Hank! // Eat dinner~ // Eat supper~ LazyMan(“Hank”).sleepFirst(5).eat(“supper”) // 等待5秒 // Wake up after 5 // Hi This is Hank! // Eat supper
這道題考察的肯定不是實現(xiàn)這個函數(shù)的能力問題,應該是流程控制的問題。解決思路應該是將所有的人如都存放到一個數(shù)組中,并在所有的方法執(zhí)行完之后一次性的輸出,實現(xiàn)的代碼如下:
function _LazyMan(name) { this.tasks = []; var self = this; var fn =(function(n){ var name = n; return function(){ console.log("Hi! This is " + name + "!"); self.next(); } })(name); this.tasks.push(fn); setTimeout(function(){ self.next(); }, 0); // 在下一個事件循環(huán)啟動任務 } /* 事件調(diào)度函數(shù) */ _LazyMan.prototype.next = function() { var fn = this.tasks.shift(); fn && fn(); } _LazyMan.prototype.eat = function(name) { var self = this; var fn =(function(name){ return function(){ console.log("Eat " + name + "~"); self.next() } })(name); this.tasks.push(fn); return this; // 實現(xiàn)鏈式調(diào)用 } _LazyMan.prototype.sleep = function(time) { var self = this; var fn = (function(time){ return function() { setTimeout(function(){ console.log("Wake up after " + time + "s!"); self.next(); }, time * 1000); } })(time); this.tasks.push(fn); return this; } _LazyMan.prototype.sleepFirst = function(time) { var self = this; var fn = (function(time) { return function() { setTimeout(function() { console.log("Wake up after " + time + "s!"); self.next(); }, time * 1000); } })(time); this.tasks.unshift(fn); return this; } /* 封裝 */ function LazyMan(name){ return new _LazyMan(name); }
我自己在思考解決方法的時候最讓我困惑的就是如果判斷Lazyman對象的方法被調(diào)用結束了?我甚至為了這個問題坐過了站。。。后來當我看到這段代碼的時候,發(fā)現(xiàn)一個簡單的setTimeout就解決了這個問題,為什么呢???
并發(fā)模型與Event?Loop這張圖是MDN對Event Loop的解釋,這張圖上分為三個部分,分別是隊列、棧、和堆。我們在理解lazyman的過程中需要知道的就是隊列和棧。首先我們來講這個棧:
在js中,每當有函數(shù)被執(zhí)行的時候都會在當前的執(zhí)行堆棧中創(chuàng)建一個新的堆棧幀,并放到棧頂。這個堆棧幀中包含當前執(zhí)行的函數(shù)的參數(shù)和局部變量。(有沒有感覺很熟悉,沒錯,這就是我們理解作用域鏈的時候的那個棧)而當我們的函數(shù)執(zhí)行完之后,這個堆棧幀就會從當前棧中移除。
隊列就是JS中用來處理異步事件的隊列,每當有新的異步事件發(fā)生,就會添加一個新的消息到隊列的尾部。當之前提到的棧為空時,JS就會來處理隊列中的消息。
舉個例子來說就是:
var a = function() { setTimeout(function(){console.log(1)},0) } var b = function(){ a() console.log(2) } // 2 // 1
這里需要注意的有
就算你不在函數(shù)中使用setTimeout,而是在全局環(huán)境中使用,setTimeout也是在正常的同步代碼執(zhí)行完之后執(zhí)行,這是因為還有宿主環(huán)境在。
setTimeOut是經(jīng)過一段時間之后直接向隊列中加入一個消息,而普通的http請求是等到有返回結果了才會將消息加入到隊列中。
普通的異步事件如果沒有事件監(jiān)聽器的話是不會操作隊列的,消息是直接被忽視掉。
Lazyman中的setTimeoutLazyman中的`setTimeout不是單單的在函數(shù)中執(zhí)行,而是在對象鏈式調(diào)用中執(zhí)行。因為是鏈式調(diào)用,所以代碼一直在同一個作用于中執(zhí)行,也就是說當前的堆棧幀一直沒有被移出棧。上面的代碼中就是利用了這個特點解決了如何判斷對象調(diào)用結束的問題。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/81319.html
摘要:計算數(shù)組的極值微信面試題獲取元素的最終前端掘金一題目用代碼求出頁面上一個元素的最終的,不考慮瀏覽器,不考慮元素情況。 Excuse me?這個前端面試在搞事! - 前端 - 掘金金三銀四搞事季,前端這個近年的熱門領域,搞事氣氛特別強烈,我朋友小偉最近就在瘋狂面試,遇到了許多有趣的面試官,有趣的面試題,我來幫這個搞事 boy 轉述一下。 以下是我一個朋友的故事,真的不是我。 ... ja...
摘要:最后畫幾張粗糙的圖,簡單描述一下這個執(zhí)行的過程因為是鏈式調(diào)用,所以在鏈上的都會入棧然后執(zhí)行,額,執(zhí)行棧少畫了和。。。 前言:昨天在群里討(jin)論(chui)技(niu)術(pi),有位老鐵發(fā)了一道他面的某公司面試題,順手保存了。今早花了一點時間把這題做了出來,發(fā)現(xiàn)挺有意思的,決定在今天認真工(hua)作(shui)前,與大家分享我的解題方案和思考過程。 題目如下(可以自己先思考一會...
摘要:關于的和以上是關于與的所有文件指令分析里面意思運行的時候執(zhí)行的是文件,運行的時候執(zhí)行的是文件。前端開發(fā)過程中需要使用到后臺的的話,可以通過配置來將相應的后臺請求代理到專用的服務器。和這三個文件就簡單設置了環(huán)境變量而已,沒什么特別的。 關于vue的npm run dev和npm run build├─build│ ├─build.js│ ├─check-versions.js│ ...
摘要:前言筆者昨天在做某公司的線上筆試題的時候遇到了最后一道關于如何實現(xiàn)的試題,題目如下實現(xiàn)一個,可以按照以下方式調(diào)用輸出輸出等待秒輸出輸出等待秒以此類推。 前言 筆者昨天在做某公司的線上筆試題的時候遇到了最后一道關于如何實現(xiàn)LazyMan的試題,題目如下 實現(xiàn)一個LazyMan,可以按照以下方式調(diào)用:LazyMan(Hank)輸出:Hi! This is Hank!LazyMan(Hank...
摘要:能不能支持數(shù)據(jù)丟失啊可以的,參考我們之前說的那個數(shù)據(jù)零丟失方案其實一個肯定是很復雜的,其實這是個開放題,就是看看你有沒有從架構角度整體構思和設計的思維以及能力。其實回答這類問題,說白了,起碼不求你看過那技術的源碼,起碼你大概知道那個技術的基本原理,核心組成部分,基本架構構成,然后參照一些開源的技術把一個系統(tǒng)設計出來的思路說一下就好 比如說這個消息隊列系統(tǒng),我們來從以下幾個角度來考慮一下 (1...
閱讀 553·2021-10-19 11:45
閱讀 1363·2021-09-30 09:48
閱讀 1477·2021-08-16 10:56
閱讀 741·2021-07-26 23:38
閱讀 3213·2019-08-30 13:15
閱讀 2599·2019-08-30 12:45
閱讀 1833·2019-08-29 12:14
閱讀 2082·2019-08-26 18:42