摘要:函數(shù)調(diào)用會在內(nèi)存形成一個(gè)調(diào)用記錄,又稱調(diào)用幀,保存調(diào)用位置和內(nèi)部變量等信息。等到運(yùn)行結(jié)束,將結(jié)果返回到,的調(diào)用幀才會消失。在進(jìn)入內(nèi)層函數(shù)的時(shí)候,可以直接用內(nèi)層函數(shù)的調(diào)用幀替換掉外層函數(shù)的調(diào)用幀,從而大大減少內(nèi)存占用。
昨晚翻了一下,雖然都是一些舊知識,不過深入下去對照著其他資料一起看,還是能發(fā)現(xiàn)一些有意思的地方。
函數(shù)式編程反正之前我是沒搞懂函數(shù)式和命令式的區(qū)別,也很疑惑函數(shù)式編程中,如果出現(xiàn)分支怎么辦,昨晚總算弄明白了。
// 我們有4個(gè)基礎(chǔ)函數(shù),會根據(jù)不同的業(yè)務(wù)邏輯進(jìn)行組裝使用 // 自動創(chuàng)建 function autoCreate () {} // 自動同步 function autoSync () {} // 流程 A function processA () {} // 流程 B function processB () {} // 流程 A 與流程 B 在業(yè)務(wù)上是互斥的
傳統(tǒng)的命令式編程,我們會這樣寫業(yè)務(wù)邏輯
function service (errorHandler) { var result; if (!id) { result = autoCreate(); if (result.error) { errorHandler(result); } } if (type === "a") { processA(); if (result.error) { errorHandler(result); } } if (type === "b") { result = processB(); if (result.error) { errorHandler(result); } } if (!isSync) { result = autoSync(); if (result.error) { errorHandler(result); } } }
而函數(shù)式編程,我們則可以這樣寫業(yè)務(wù)邏輯。
// service 本身不是一個(gè)異步業(yè)務(wù),所以直接使用 Promise.resolve() var service = Promise.resolve(); // 需要對autoCreate()等四個(gè)基礎(chǔ)函數(shù)做 Promise 改造 service.then(autoCreate) .then(processA) .then(processB) .then(autoSync) .catch(errorHandler);
這里可能會有一個(gè)疑惑,互斥的 processA 和 processB 怎么進(jìn)入了同一個(gè)處理流程,這樣和需求就不符合了?
在這種情況下,我們還需要在 processA 和 processB 的內(nèi)部,把退出條件補(bǔ)上。
function processA () { return new Promise(function(resolve, reject){ if (type !== "A") { resolve(); } // 這里繼續(xù) processA 的邏輯代碼 }); }調(diào)用棧
JS 在執(zhí)行的時(shí)候,有一個(gè)函數(shù)調(diào)用棧,棧里面放著一個(gè)個(gè)的函數(shù)調(diào)用幀,這些幀保存著所屬函數(shù)所需的所有變量信息。
瀏覽器攔截 window.open函數(shù)調(diào)用會在內(nèi)存形成一個(gè)“調(diào)用記錄”,又稱“調(diào)用幀”(call
frame),保存調(diào)用位置和內(nèi)部變量等信息。如果在函數(shù)A的內(nèi)部調(diào)用函數(shù)B,那么在A的調(diào)用幀上方,還會形成一個(gè)B的調(diào)用幀。等到B運(yùn)行結(jié)束,將結(jié)果返回到A,B的調(diào)用幀才會消失。如果函數(shù)B內(nèi)部還調(diào)用函數(shù)C,那就還有一個(gè)C的調(diào)用幀,以此類推。所有的調(diào)用幀,就形成一個(gè)“調(diào)用?!保╟all
stack)。
我們發(fā)現(xiàn)有時(shí)候執(zhí)行 window.open(),能正常打開新窗口或者新的標(biāo)簽頁,而有時(shí)卻又不行,會被瀏覽器攔截。
其原因是瀏覽器會根據(jù)當(dāng)前調(diào)用棧,找到最初的caller,如果不是用戶觸發(fā)的,則攔截。
尾調(diào)用優(yōu)化由于函數(shù)調(diào)用的時(shí)候會生成新的調(diào)用幀,當(dāng)遞歸調(diào)用的時(shí)候,調(diào)用棧中的調(diào)用幀增長會非常厲害,最終導(dǎo)致內(nèi)存耗盡而觸發(fā) RangeError。
如果把函數(shù)調(diào)用放在函數(shù)塊的最后一條語句,且不在使用外層函數(shù)的變量了,則外層函數(shù)所占用的調(diào)用幀已無存在意義。在進(jìn)入內(nèi)層函數(shù)的時(shí)候,可以直接用內(nèi)層函數(shù)的調(diào)用幀替換掉外層函數(shù)的調(diào)用幀,從而大大減少內(nèi)存占用。
其他Partial Application 的模式,用來做 Library 和 SDK 都挺好的。一個(gè)可定制性高的底層接口,再通過類似 _.partial() 的方式,提供一個(gè)開箱即用的上層接口。就像 $.ajax() 和 $.get() 一樣。
_.defer() 和 _.memoize() 可以用在有大運(yùn)算量的業(yè)務(wù)場景。
同步于我的博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86549.html
摘要:計(jì)算機(jī)科學(xué)中最常見的兩種數(shù)據(jù)結(jié)構(gòu)是單鏈表和雙鏈表。雙向鏈表雙向鏈表具有單鏈表的所有功能,并將其擴(kuò)展為在鏈表中可以進(jìn)行雙向遍歷。雙向鏈表的操作我們的鏈表將包括兩個(gè)構(gòu)造函數(shù)和。與單鏈表不同,雙向鏈表包含對鏈表開頭和結(jié)尾節(jié)點(diǎn)的引用。 翻譯:瘋狂的技術(shù)宅英文:https://code.tutsplus.com/art...說明:本文翻譯自系列文章《Data Structures With Ja...
摘要:你已經(jīng)聽說過上下文參數(shù),但是還沒有碰到使用的場合。傳遞一個(gè)選擇器表達(dá)式,一個(gè)對象,一個(gè)集合,或者一個(gè)節(jié)點(diǎn)給上下文參數(shù),將盡在這個(gè)上下文中搜索元素。 你已經(jīng)聽說過上下文參數(shù),但是還沒有碰到使用的場合。再想$()中,傳遞選擇器的時(shí)候,可以傳遞第二個(gè)參數(shù),指定上下文,jQ將在這個(gè)上下文中搜索匹配選擇器表達(dá)式的元素,上下文參數(shù)可能是利用最不充分的JQ功能,其用法非常簡單。傳遞一個(gè)選擇器表達(dá)式,...
摘要:在上一篇文章中,我們了解了隊(duì)列和棧的描述,現(xiàn)在讓我們來了解一下單鏈表和雙向鏈表的實(shí)現(xiàn)。單鏈表和雙向鏈表具有以下特點(diǎn)可動態(tài)分配空間,但不能隨機(jī)訪問。 在上一篇文章中,我們了解了隊(duì)列和棧的JavaScript描述,現(xiàn)在讓我們來了解一下 單鏈表 和雙向鏈表 的實(shí)現(xiàn)。本文的代碼并非所有都由本人所寫,只是出于學(xué)習(xí)目的,在此分享出來,并加上一定的解釋,便于大家學(xué)習(xí)。 本系列文章的代碼可在ht...
摘要:這是我收集的一些資源,分享給大家,全部放在百度網(wǎng)盤,有需要的請轉(zhuǎn)存到自己的網(wǎng)盤或者下載,以免網(wǎng)盤鏈接失效,另外還有幾百的視頻文件存在網(wǎng)盤,需要的加全部分享在空間,自己可以去下載與權(quán)威指南配套源碼禪意花園高清源碼基礎(chǔ)教程權(quán)威指南參考手冊鋒利 這是我收集的一些資源,分享給大家,全部放在百度網(wǎng)盤,有需要的請轉(zhuǎn)存到自己的網(wǎng)盤或者下載,以免網(wǎng)盤鏈接失效,另外還有幾百G的視頻文件存在網(wǎng)盤,需要的加...
摘要:我們很容易修改緩存驅(qū)動方式。這樣的話,我們甚至根本不必檢查緩存是否過期。與驅(qū)動相比,和的速度更快,所以建議在項(xiàng)目較大時(shí)使用外部緩存驅(qū)動。結(jié)論使用文件數(shù)據(jù)庫作為驅(qū)動,兩者在速度上沒有很明顯的區(qū)別。所以投資高速緩存是值得的。 showImg(https://segmentfault.com/img/remote/1460000014057714?w=1440&h=720); 緩存是web開...
閱讀 1323·2021-11-16 11:45
閱讀 2247·2021-11-02 14:40
閱讀 3888·2021-09-24 10:25
閱讀 3035·2019-08-30 12:45
閱讀 1267·2019-08-29 18:39
閱讀 2479·2019-08-29 12:32
閱讀 1617·2019-08-26 10:45
閱讀 1926·2019-08-23 17:01